Follow us on Twitter X-Cart on Facebook Wiki
Shopping cart software Solutions for online shops and malls

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

 
Reply
   X-Cart forums > X-Cart 5 > Modifying the design and features (X-Cart 5)
 
Thread Tools Search this Thread
  #1  
Old 11-06-2014, 06:07 AM
 
drholmes drholmes is offline
 

Advanced Member
  
Join Date: Oct 2014
Posts: 72
 

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.0.6, No third party modules, most modules disabled, zero modifications other than CSS.
Reply With Quote

The following 2 users thank drholmes for this useful post:
tony_sologubov (11-11-2014), totaltec (11-06-2014)
  #2  
Old 11-06-2014, 01:18 PM
  totaltec's Avatar 
totaltec totaltec is offline
 

X-Guru
  
Join Date: Jan 2007
Location: Louisville, KY USA
Posts: 5,823
 

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

Very nicely done sir. I'm sure this will help others.
__________________
Mike White - Now Accepting new clients and projects! Work with the best, get a US based development team for just $125 an hour. Call 1-502-773-6454, email mike at babymonkeystudios.com, or skype b8bym0nkey

XcartGuru
X-cart Tutorials | X-cart 5 Tutorials

Check out the responsive template for X-cart.
Reply With Quote
  #3  
Old 11-06-2014, 01:43 PM
 
drholmes drholmes is offline
 

Advanced Member
  
Join Date: Oct 2014
Posts: 72
 

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

Thanks, Mike.

Here's the variation I talked about. Many people will have a CMS where they can't just break the page up into individual chunks in different HTML pages. Instead, they'll be able to put some comments into their CMS template, and then the following alternative pullCMSHeadContent() function will extract the part they marked:

Code:
public function pullCMSHeadContent() { $source = file_get_contents("http://www.example.com/blankpage.html"); $startMarker = "<!-- HEAD START -->"; $endMarker = "<!-- HEAD END -->"; $startPos = strpos($source, $startMarker); $endPos = strpos($source, $endMarker); if ($startPos === false || $endPos === false) return ''; $startMarkerLen = strlen($startMarker); $output = substr($source, $startPos + $startMarkerLen, ($endPos - $startPos) - $startMarkerLen); return $output; }

Then using CNN.com as an example, here's how you would modify your basic CMS template (the same template used for all pages in your CMS):

Code:
<link href="http://www.cnn.com/" rel="canonical"/> <link href="http://www.cnn.com/favicon.ie9.ico" rel="Shortcut Icon" type="image/x-icon"/> <link href="/tools/search/cnncom.xml" rel="search" title="CNN.com" type="application/opensearchdescription+xml"/> <!-- HEAD START --> <link href="/tools/search/cnncomvideo.xml" rel="search" title="CNN.com Video" type="application/opensearchdescription+xml"/> <link href="http://i.cdn.turner.com/cnn/.e/img/3.0/global/misc/apple-touch-icon.png" rel="apple-touch-icon" type="image/png"/> <link href="http://rss.cnn.com/rss/cnn_topstories.rss" rel="alternate" title="CNN - Top Stories [RSS]" type="application/rss+xml"/> <link href="http://rss.cnn.com/rss/cnn_latest.rss" rel="alternate" title="CNN - Recent Stories [RSS]" type="application/rss+xml"/> <!-- HEAD END --> <link href="http://edition.cnn.com" hreflang="en-gb" rel="alternate" title="CNN International" type="text/html"/> <link href="http://arabic.cnn.com" hreflang="ar" rel="alternate" title="CNN Arabic" type="text/html"/> <link href="http://mexico.cnn.com" hreflang="es" rel="alternate" title="CNN Mexico" type="text/html"/>

So you just put HTML comments into your main CMS template, and these parts get reused in X-Cart. If you make a blank page, and then insert this for your <head> content (exclude the <title> tag, it's better that X-Cart generates it, you mark another range for after <body> until the content, and the final range for after-content-until-</body>, then X-Cart gets wrapped into your site.

A little caveat, this adds CPU overhead. Especially because you're pulling the same page 3 times. Even if it's coming from a static cache, it's three times processing. It would be better to store it and use it three times. Or to only extract your segments one time and store them until the source has changed.

Anyway, these examples are very basic, I just feel that that's what we need in order to get a handle on the massive X-Cart structure. And they're just to show the principle as I imagine it. This isn't, and shouldn't be rocket science. I've just been stumped with the X-Cart documentation, which reads like a phone book, and there are bugs in the examples, so I've actually spent two days getting to this Hello World example.

But I have it running beautifully here. The rest of the stuff we do runs directly on the database, so I won't likely need to write any more modules. That's why I was trying to avoid getting a whole education in X-Cart development just to do this one thing

Best,

Per


Per
__________________
X-Cart Business 5.4.0.6, No third party modules, most modules disabled, zero modifications other than CSS.
Reply With Quote
Reply
   X-Cart forums > X-Cart 5 > Modifying the design and features (X-Cart 5)


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -8. The time now is 03:24 AM.

   

 
X-Cart forums © 2001-2020