Nov
26
SkyBlueCanvas Fragments Explained
Filed Under Fragments, SkyBlueCanvas CMS
The key buidling dynamic content into a SkyBlueCanvas site is what we call fragments. An easy way to think about fragments is as a piece of a page. The fragment code creates the HTML for a particular data type. For instance, if you have a collection of Links you want to display on your site, the Links Fragment will take care of generating the HTML. One neat thing about fragments, though, is that a single fragment can have numerous different HTML formats.
Creating a basic fragment is pretty simple. You simply go to /your_skyblue_root/data/skins/your_skin/ and create a new folder named fragments. Inside this folder, you create another folder named links. There are two pre-defined files that you can create in this folder but both are optional.
functions.php
If you create a file named functions.php in your /fragments/your_fragment/ folder, SkyBlueCanvas will load this file automatically before loading your fragment. This allows you to creat more robust fragments without cluttering your presentation code with a lot of logic.
view.php
view.php is the default fragment view name. You can name your views anything you like. The significance of the view.php file will be explained a little later on when we talk about Loading Fragments in a web page.
By default, SkyBlueCanvas will attempt to figure out which data set to make available to your fragment view. It does this by matching the fragment name (for instance Links) with an existing data set. If the fragment name correspongs to an Admin Manager name, that data set will be loaded and made available to your fragment view in a variable named $data. For very simple fragments that use a single data set, this means you don’t need to write any code to retrieve the data set.
About Data Sets
SkyBlueCanvas stores data objects in an XML file named according to the Admin Manager that manages that data set. Using our Links Manager as an example, SkyBlueCanvas stores Links data in /skyblue_root/data/xml/links.xml.
If the Admin Manager also has groups associated with the data objects, then the data is usually stored in a file named [data]groups.xml. Again using the Links Manager as an example, the Links Groups are stored in /skyblue_root/data/xml/linksgroups.xml.
A Simple Example
Theory is wonderful, but examples are perhaps more useful so let’s create a simple fragment so you can get the hang of it.
If you do not have a folder named fragments in your skin folder, create it now. Inside that directory, create a new directory named links. The, inside the links folder, create two PHP files: functions.php and view.php.
This is not a lesson on writing PHP, so I will just give you the code to paste into functions.php:
<?php
function get_published(&$items) {
$pub = array();
foreach ($items as $item) {
if (!isset($item->published)) {
array_push($pub, $item);
}
else if ($item->published) {
array_push($item->published);
}
}
return $pub;
}
function get_items(&$group, $items) {
$items = get_published($items);
$these = array();
foreach ($items as $item) {
if ($item->group == $group->id) {
if ($item->groups == $group->id) {
array_push($these, $item);
}
}
return $these;
}
?>
The View
The view is where the data items are transformed into HTML. A little bit of PHP is required, however, to make sure we have all the data we need. So past the following code into view.php:
<?php
global $Core;
global $Filter;
$groups = get_published(
$Core->xmlHandler->ParserMain(
"data/xml/linksgroups.xml"
)
);
$items = get_published($data);
unset($data);
?>
This code is very easy to understand. First, we declare the Core and Filter objects as global. This allows us to access these items which were created in the global scope of the PHP script (index.php).
in the next section of the code, we are getting all of the published groups, by calling get_published (from functions.php) with the output of the xmlHandler.
In the last piece of code, we are fitlering our complete list of data items in $data, by getting the published links with get_published.
Then, just for good house-keeping, we unset the $data variable because it is no longer needed.
The Output
The next bit creates the actual output using our data items and groups.
<div>
<?php foreach ($groups as $group) : ?>
<?php $data = get_items($group, $items); ?>
<h2>
<?php echo $group->name; ?>
</h2>
<ul class="links">
<?php if (count($data)) : ?>
<?php foreach ($data as $obj) : ?>
<li>
<a href="<?php echo $obj->url; ?>">
<?php echo $obj->name; ?>
</a>
</li>
<?php endforeach; ?>
<?php endif; ?>
</ul>
<?php endforeach; ?>
</div>
Let’s look at this block of code in smaller pieces. In the outer-most block of code, we are simply looping through all of the groups. Each pass through the loop, the next group is stored in the $group variable so we can access it’s data.
<div> <?php foreach ($groups as $group) : ?> <?php endforeach; ?> </div>
In the next block, we are retrieving all of the items in the current group:
<div>
<?php foreach ($groups as $group) : ?>
<?php $data = get_items($group, $items); ?>
<?php endforeach; ?>
</div>
And finally, we loop through each item in $items. Each pass through the loop, the next item is stored in the $item variable.
<div>
<?php foreach ($groups as $group) : ?>
<?php $data = get_items($group, $items); ?>
<h2><?php echo $group->name; ?></h2>
<ul class="links">
<?php if (count($data)) : ?>
<?php foreach ($data as $obj) : ?>
<li>
<a href="<?php echo $obj->url; ?>">
<?php echo $obj->name; ?>
</a>
</li>
<?php endforeach; ?>
<?php endif; ?>
</ul>
<?php endforeach; ?>
</div>
You will notice that there is HTML code mixed with the PHP code. When view.php is loaded, the PHP will be executed and merged with the HTML.
The Full Code
<?php
global $Core;
global $Filter;
$groups = get_published(
$Core->xmlHandler->ParserMain(
"data/xml/linksgroups.xml"
)
);
$items = get_published($data);
unset($data);
?>
<div>
<?php foreach ($groups as $group) : ?>
<?php $data = get_items($group, $items); ?>
<h2><?php echo $group->name; ?></h2>
<ul class="links">
<?php if (count($data)) : ?>
<?php foreach ($data as $obj) : ?>
<li>
<a href="<?php echo $obj->url; ?>">
<?php echo $obj->name; ?>
</a>
</li>
<?php endforeach; ?>
<?php endif; ?>
</ul>
<?php endforeach; ?>
</div>
Loading Fragments
Well, the hard part is over. All we need to do now is tell SkyBlueCanvas where to load the fragment. This is very easy and there are two ways to do it.
You can load fragments as part of a template or within the body (text) of a page. To load a fragment as part of the template, you simply include the following code in the the desired location of the template:
<!--#plugin:fragment(links,view)-->
If you recall, however, I stated earlier that view.php is the default view file, so the view argument in the code just given is not needed. So you can load the links fragment with this code:
<!--#plugin:fragment(links)-->
If you want to display your links in the body of a page or text article, you can do so by inserting the following token in the body of your page text:
{plugin:fragment(links)}
You can try this technique out by going to Admin > Pages and inserting the token above in the page text.
Caveats
In order for the fragments to work, you will need to make sure that the PluginParser and FragmentsPlugin are enabled. To do this, go to Admin > Collections > Plugins and make sure plugin.parser.php and plugin.fragments.php are loaded.
Comments
13 Responses to “SkyBlueCanvas Fragments Explained”
Leave a Reply
[...] You can find a full tutorial on Fragments in the post about Fragments [...]
[...] See also: SkyBlueCanvas Skins Explained SkyBlueCanvas Fragments Explained [...]
[...] Fragments Explained [...]
Slight typo:
“in the next section of the code, we are getting all of the published groups, by calling get_published (from functions.php) with the output of the xmlHandler.”
The sentence starts with ‘in’ instead of ‘In’
Good document, I do need to freshen up on my php though.
[...] can also learn more about Fragments in the Fragments Explained post on our [...]
Hello, I have installed SkyBlue with I’m not able to insert footer fragments… I don’t see anything related to “fragments” in the admin area. Where do I have to go Thank you Franz
You insert fragments into the HTML template. You do this by opening your template in an HTML editor and adding the fragment token <!–#plugin:fragment(footer,view)–> directly into the HTML. There is no admin GUI for doing this (unless you do it via the Skins HTML editor).
This is just not clear. It talks about two pages. no mention if they are just examples. So I can only use these two pages? I get an error when installing a new fragment andmy uploaded fragment in the fragments folder wont load into the page.
I am using:
For a top-nav.php file in the fragments folder. I have also tried the curly braket version of the tag.
I think this tutorial needs a little more explanation (read hand-holding). Perhaps use XYZ.php file names to avoid confusion?
Sorry if it is not clear. There are two pieces to the fragment, the fragment folder, and the fragment file. So if your fragment is a “top-nav”, create a folder named “top-nav” inside the data/skins/your_skin/fragments/ directory:
data/skins/your_skin/fragments/top-nav/
Then, inside the top-nav directly, create a PHP file. You indicated you named your file “top-nav.php”. That is fine so you would have:
data/skins/your_skin/fragments/top-nav/top-nav.php
Then in your code, add this:
<!–#plugin:fragment(top-nav,top-nav)–>
It’s important to note that this is:
<!–#plugin:fragment(foldername,filename)–>
I should take this to the forum.
So everything that I want to include that is NOT necessarily changeable content, but rather various part of page construction, should have its own folder in fragments and the content in ‘view’ or [anyothername].php
Ok got that, moving on to page content, thank you Scott for your time
WJ
My pleasure. Feel free to ping me with any other questions you have.
Hi Scott,
There seems to be a typo in the code you suggest pasting into the functions.php above:
if ($item->group == $group->id) {
array_push($these, $item);
}
should be
if ($item->groups == $group->id) {
array_push($these, $item);
}
The “group” attribute doesn’t exist in the item, only “groups”.
Great tutorial, just got my articles printing as if they were links, now playing with actual display. So much fun!
Good catch. I will make the correction in the text. Thanks for pointing out my mistake.