View Single Post
  #1  
Old 11-06-2014, 06:07 AM
 
drholmes drholmes is offline
 

Advanced Member
  
Join Date: Oct 2014
Posts: 84
 

Default How to integrate X-Cart 5 with a CMS site: Tutorial

Hi,

I've been struggling for a while to get content pulled from our CMS, and I finally worked it out. The X-Cart documentation leaves much to be desired, so I'm trying to post the tutorial I wish I had, so somebody else may save the time.


This is a pretty hard-coded example because I have a specific problem to solve, and I'm trying not to have to become an expert on the entire X-Cart class structure just to do this thing. Two things would be worth it to do for this to be a more useful module for everyone:

  • It ought to be configurable in a control panel. Everything is hard-coded into the module.
  • It ought to have more ways to pull from the CMS, for example just pulling a single CMS page and using HTML comments (e.g. <!-- HEADER START/END --> to extract the parts you need.
So the objective is:This way, we can get our site CSS and Javascript into the header, and the top and bottom of our page HTML will appear before and after all of X-Cart.

CREATING THE MODULE

Create a folder xcart/classes/XLite/Module/HCW/CMSContent <-- HCW is the name of our company, CMSContent is the name of the module.

Inside that folder, create a file Main.php containing:

Code:
<?php namespace XLite\Module\HCW\CMSContent; abstract class Main extends \XLite\Module\AModule { /** * Author name * * @return string */ public static function getAuthorName() { return 'HCW'; } /** * Module name * * @return string */ public static function getModuleName() { return 'CMS Content'; } /** * Get module major version * * @return string */ public static function getMajorVersion() { return '5.1'; } /** * Module version * * @return string */ public static function getMinorVersion() { return 0; } /** * Module description * * @return string */ public static function getDescription() { return 'Pulls CMS Content and renders it into <head> tag, after <body> and before </body>'; } }


Nothing special here, this is the default blank module example from X-Cart's website.

Next, create a folder View in your module folder (total path will be xcart/classes/XLite/Module/HCW/CMSContent/View). Inside that folder, we're creating 3 nearly identical files. I'll paste them first and explain afterwards:

Create the file PullHeadContent.php:

Code:
<?php namespace XLite\Module\HCW\CMSContent\View; /** * @ListChild (list="head", zone="customer", weight="10000") */ class PullHeadContent extends \XLite\View\AView { protected function getDefaultTemplate() { return 'modules/HCW/CMSContent/head.tpl'; } public function pullCMSHeadContent() { return file_get_contents("http://www.example.com/headcontent.html"); } }


Create the file PullBodyTopContent.php:

Code:
<?php namespace XLite\Module\HCW\CMSContent\View; /** * @ListChild (list="body", zone="customer", weight="-10000") */ class PullBodyTopContent extends \XLite\View\AView { protected function getDefaultTemplate() { return 'modules/HCW/CMSContent/bodytop.tpl'; } public function pullCMSBodyTopContent() { return file_get_contents("http://www.example.com/bodytopcontent.html"); } }


And finally, create the file PullBodyBottomContent.php:

Code:
<?php namespace XLite\Module\HCW\CMSContent\View; /** * @ListChild (list="body", zone="customer", weight="99999") */ class PullBodyBottomContent extends \XLite\View\AView { protected function getDefaultTemplate() { return 'modules/HCW/CMSContent/bodybottom.tpl'; } public function pullCMSBodyBottomContent() { return file_get_contents("http://www.example.com.com/bodybottomcontent.html"); } }


What to notice:
  • How this works is that the getDefaultTemplate() function (which is a required function) tells X-Cart the path to the template file (we'll do that one in a minute)
  • The template file will contain the template code that calls the pullCMSBodyBottomContent()
  • Notice the @ListChild command in the comment block. That's not a comment, that's an actual command to select which list (part of page) it goes into, and its weight (order). The body contents both go into the body list, but one goes at the top (weight=-10000), another goes at the bottom (weight=99999).
  • Make sure that if you change the name of the module that you change all the namespaces as well, otherwise Re-deploy crashes.
  • Be aware that the class inside the module must have the same name as the PHP file. If you change the PHP file to "HelloThere.php", the class must become "class HelloThere {}". Otherwise it won't compile.
CREATING THE TEMPLATES:

The templates go inside the skin, so create the folder xcart/skins/default/en/modules/HCW/CMSContent/ (you're creating only the HCW/CMSContent folders, the rest are already there). Inside that, create 3 files:

Create head.tpl (this is lowercase on purpose):

Code:
{pullCMSHeadContent():h}


Create bodytop.tpl:

Code:
{pullCMSBodyTopContent():h}


And finally, create bodybottom.tpl:

Code:
{pullCMSBodyBottomContent():h}


What to notice:
  • This is the Flexy template code that calls the function we defined in the module.
  • Notice the ":h" flag after the function call. This ensures that the output is rendered untouched. Without this flag, your CMS HTML is escaped (< becomes &lt, and is useless.
Redeploy the store, activate the module, Redeploy the store again, and you're good to go:

PRACTICAL PROBLEMS:
  • Pulling from a CMS should be fast if the pages are cached. On the very first load, the CMS caches the pages, and then the next time X-Cart fetches, Apache is serving the HTML from a static cache. Make sure that caching is enabled in your CMS for these pages that you pull from.
  • It's problematic to overlay two sites' CSS on top of each other, and there's some weirdness that has to be worked out. Everybody is fighting to control all the tags.
So, I hope this solves somebody's problem. Feel free to ask questions, but remember, I'm not an expert on X-Cart, I'm just a guy trying to figure it out.

Per
__________________
X-Cart Business 5.4.1.7, No third party modules, most modules disabled, zero modifications other than CSS.
Reply With Quote