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”

  1. SkyBlueCanvas - SkyBlueCanvas v1.1 RC1 Skins Explained on November 26th, 2008 1:20 am

    [...] You can find a full tutorial on Fragments in the post about Fragments [...]

  2. SkyBlueCanvas - Installing SkyBlueCanvas Galleria Extension on November 27th, 2008 10:41 am

    [...] See also: SkyBlueCanvas Skins Explained SkyBlueCanvas Fragments Explained [...]

  3. SkyBlueCanvas - Creating Menus in SkyBlueCanvas v1.1 on November 27th, 2008 12:59 pm

    [...] Fragments Explained [...]

  4. Kordain on February 4th, 2009 5:46 pm

    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.

  5. SkyBlueCanvas - SkyBlueCanvas FormBuilder on February 22nd, 2009 1:02 am

    [...] can also learn more about Fragments in the Fragments Explained post on our [...]

  6. Franz on March 31st, 2009 4:07 am

    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

  7. scott on March 31st, 2009 8:24 am

    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).

  8. Leif Croonquist on February 22nd, 2010 12:30 pm

    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?

  9. scott on February 22nd, 2010 12:39 pm

    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)–>

  10. Leif Croonquist on February 22nd, 2010 12:58 pm

    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

  11. scott on February 22nd, 2010 1:01 pm

    My pleasure. Feel free to ping me with any other questions you have.

  12. Masha on May 9th, 2010 10:36 am

    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! :)

  13. scott on May 9th, 2010 10:46 am

    Good catch. I will make the correction in the text. Thanks for pointing out my mistake.

Leave a Reply