Creating a Concrete5 Package: Integrating the Craftyslide JQuery Plugin

5th July 2011 | Tags:

In this sim­ple tuto­r­ial, I’m going to show how Concrete5 can be extended to inte­grate a third-​party JQuery plu­gin to enhance an exist­ing mod­ule, and then how this can be encap­su­lated in a pack­age. I’m going to allow the slideshow mod­ule to dis­play images using the clean & light­weight Craftys­lide plu­gin, pic­tured below.

The Craftyslide JQuery Slider plugin in action
The Craftys­lide plu­gin in action

Concrete5 comes shipped with sim­ple slideshow func­tion­al­ity in the form of a block called, imag­i­na­tively enough, slideshow. As this is part of the core you can find it in /concrete/blocks/slideshow. It’s in the con­crete direc­tory to keep it sep­a­rate from cus­tom code. And some cus­tom code is what we’re going to pro­duce — to over­ride the out­put of that block, and then to encap­su­late this into a package.

First Steps

Obvi­ously you’ll need to down­load and install Concrete5. Down­load Craftys­lide from the project page and unpack the archive somewhere.

Cre­at­ing a Slideshow

Before start­ing the inte­gra­tion, let’s cre­ate a sim­ple slideshow using this built-​in func­tion­al­ity — once we’ve built our add-​on this can then be re-​configured to use Craftys­lide. It’s prob­a­bly most appro­pri­ate to cre­ate a slideshow from a set (rather than all the images in the site!) so let’s do that first. From the Dash­board, select File Man­ager from the left-​hand menu. The File Man­ager lets you man­age uploaded files, includ­ing images.

Concrete5's File Manager
The File Man­ager in Concrete5

If you don’t have any images, add them now. Tick the boxes along­side the images you wish to group in a set, then select Sets in the drop-​down at the top of the table of files. You’ll get the dia­log pic­tured below.

Sets in Concrete5 allow you to group photos within the File Manager
Sets in Concrete5 allow you to group pho­tos within the File Manager

Click the check­box under Add to a New Set, give the new set a name and click Add (of course, if you have pre­vi­ously added a set it will be avail­able here).

Adding a Title

The Craftys­lide plu­gin fea­tures a title con­trol (see the pic­ture which intro­duces this post), so we’ll need to assign these to the images in the set. Go back to the file man­ager, click an image and select Prop­er­ties. You’ll get the dia­log shown below; click Title, assign one, click the icon to the right of the input and close the dia­log. Repeat for each of your images.

Specifying file properties in Concrete5
Enter a title for the file, to be dis­played within the slider

Adding a Slideshow Block

Now that you have a num­ber of images organ­ised into a set, you can use this as the basis for a slideshow block. Nav­i­gate to the web­site (Return to Web­site from the dash­board), click a region, then select Add Block to bring up the dia­log below.

Adding a Block in Concrete5
Select Slideshow

The slideshow block is avail­able out-​of-​the-​box, so select that and you’ll get the fol­low­ing dialog.

Configuring the new slideshow block
Select Pic­tures from File Set, and then select the set you have just created.

Select the new set you’ve just cre­ated and click Add. At this point, if you go back to the page you added the slideshow to, you should see it in action; what we’re going to do now is re-​work it so that it uses the Craftys­lide plugin.

The Direc­tory Structure

Before we start doing any edit­ing, let’s look at the direc­tory struc­ture. The image below shows the struc­ture we’re going to create.

Directory structure for a Concrete5 Package
This fig­ure shows the direc­tory struc­ture required for our new Package

Going from the top-​level direc­tory down, here is an overview of the struc­ture. First off, every­thing goes in the packages direc­tory; not the one which is in concrete as this is reserved for the core files. The pack­age is called craftyslide so that goes next. Our pack­age is encap­su­lat­ing block-​related func­tion­al­ity, so we then have a direc­tory called blocks. Rather than cre­ate a new block, how­ever, we’re extend­ing the slideshow block, and cre­at­ing a tem­plate, so we put that in a direc­tory named accord­ingly — templates. The tem­plate is going to be called craftyslide to match the name of the pack­age, and it’s the name of this direc­tory which is used in the back-​end to ref­er­ence the tem­plate, as we’ll see later. We cre­ate an images direc­tory, and js is named as it is for a rea­son; any JavaScript files in a direc­tory with that name are auto­mat­i­cally included. The struc­ture takes some get­ting used to, but look­ing at the struc­ture under the concrete direc­tory and at exist­ing pack­ages helps to under­stand how it’s all organised.

Inte­grat­ing Craftys­lide — Cre­at­ing the Template

The out­put from the slideshow block is, by con­ven­tion, ren­dered by the file view.php in the /concrete/blocks/slideshow direc­tory. If you open that up you’ll notice — amongst a bunch of Javascript that pow­ers it — there’s a loop which iter­ates through the images thus:

foreach($images as $imgInfo){

The default slideshow works by cre­at­ing skele­ton markup, then cre­at­ing JavaScript code in which the filepaths of the images are embed­ded pro­gram­mat­i­cally. The Craftys­lide plu­gin, how­ever, works by tak­ing some markup and apply­ing a JQuery func­tion to that markup. As such, we want to do the fol­low­ing (this is saved as /packages/craftyslide/blocks/slideshow/templates/craftyslide/view.php): ‘

<?php defined('C5_EXECUTE') or die("Access Denied."); ?>
<div id="slideshow<?php print $bID ?>">
    <ul>
    <?php foreach($images as $imgInfo): 
        $f = File::getByID($imgInfo['fID']);
        $fp = new Permissions($f);          
        if ($fp->canRead()):
    ?>          
    <li>
        <img src="<?php print $f->getRelativePath(); ?>" title=<?php print $f->getTitle(); ?>" />
    </li>
    <?php endif; ?>
<?php endforeach; ?>
    </ul>
</div>

I’ll go through the impor­tant lines.

  • line 1 con­tains a quick check to ensure this file never gets run as stand­alone script. You’ll find this through­out the code.
  • In line 2 we cre­ate a DIV with a name tied to the block, by append­ing the block ID — stored in the $bID variable.
  • In line 4 we start to iter­ate through the images in our set
  • Each ele­ment in the array of images con­tains ref­er­ences to file objects, so line 5 grabs the object that rep­re­sents the file
  • In line 6 we obtain an object which tells us about the per­mis­sions on the file object with respect to the cur­rent site user, so:
  • Line 7 checks that the cur­rent user should be able to see this image. (Unpub­lished images should be hid­den from a vis­i­tor, for example.)
  • In line 10 we cre­ate an img tag, with the path to the image and the title taken from the cur­rent file object.

Inte­grat­ing Craftys­lide — Adding Styles

When cre­at­ing a block there’s a sim­ple con­ven­tion for apply­ing styles. A file named

view.css in the block’s direc­tory will be auto­mat­i­cally linked when ren­der­ing the block. Copy the file css/craftslide.css from the Craftys­lide archive and rename it view.css. This file ref­er­ences one image — pagination.png — so copy that into the block’s direc­tory and check that you’ve ref­er­enced it prop­erly in your CSS.

Inte­grat­ing Craftys­lide — JavaScript

We now need to add some JavaScript to make Craftys­lide work. There are two things which can help add JavaScript to a block. Sim­i­lar to the style rules, a file named view.js will auto­mat­i­cally be included. Then, any JavaScript files in a direc­tory called js will get added auto­mat­i­cally. It might make sense to include the library in the js folder and then ini­tialise the slideshow in view.js — how­ever this won’t work for two reasons:

  1. view.js gets included before the js direc­tory, and there­fore the Craftys­lide plu­gin won’t be loaded in time.
  2. We cre­ated our DIV’s ID dynam­i­cally using PHP, so we’ll need to do the same again for the ini­tial­i­sa­tion function

What we’ll do, then, is sim­ply add the code to ini­tialise Craftys­lide in the tem­plate (view.php), like this:

Note that we’re append­ing the Block ID $bID to cre­ate a match­ing ID. This is the most basic ini­tial­i­sa­tion of Craftys­lide, feel free to cus­tomise it accord­ingly. Then to make it work, copy either js/craftyslide.js or js/craftyslide.min.js into your block’s js direc­tory. (You’re prob­a­bly best using the mini­fied ver­sion, as there is no minif­ca­tion out-​of-​the-​box — how­ever there are ways around that.)

Apply­ing the Template

Now that we’ve cre­ated a new tem­plate for the Craftys­lide plu­gin, we need to go back to teh slidehsow block we cre­ated and apply the tem­plate to it, con­vert­ing it from the out-​of-​the-​box slideshow to a Craftyslide-​powered slider. Go to the page you placed the slideshow on, enter edit mode and click the slideshow. From the menu select Cus­tom Tem­plate to bring up the dia­log shown below.

Specifying a Custom Template for a block in Concrete5
Spec­i­fy­ing a Cus­tom Tem­plate for a block in Concrete5

Select Craftys­lide and then Update. If you leave Edit mode, you should find that the slideshow block has been replaced by a Craftys­lide slider. Let”s now wrap this up in a pack­age, so that this func­tion­al­ity can be encap­su­lated for use on other projects.

Cre­at­ing a Package

In order to tell Concrete5 about the pack­age, we cre­ate a sub­class of Pack­age and save it — per­haps slightly mis­lead­ingly — as controller.php in /packages/craftyslide. The con­tents are shown below. ‘

<?php
defined('C5_EXECUTE') or die(_("Access Denied."));

class craftyslidePackage extends Package {

    protected $pkgHandle = 'craftyslide';
    protected $appVersionRequired = '5.4.0';
    protected $pkgVersion = '1.0';

    public function getPackageDescription() {
        return t("Integrates the Craftyslide plugin for slideshows");
    }
    public function getPackageName() {
        return t("craftyslide");
    }
    public function install() {
        $pkg = parent::install();
    }
}

As you can see, the new pack­age class defines a num­ber of prop­er­ties and meth­ods. These should all be self-​explanatory.

The install() method would typ­i­cally carry out tasks such as defin­ing new blocks or jobs, but isn’t nec­es­sary here — I’ve included it nonethe­less to show where such tasks would go.

Final Steps

Finally, you may (but aren’t required to) cre­ate an icon which will be dis­played in the admin­is­tra­tive area (and in the Mar­ket­place, should you wish to dis­trib­ute your pack­ages) — you sim­ply need to ensure that it is 97px x 97px square, has 4px rounded cor­ners, is named icon.png and is saved in the package’s directory.

Comments

    Hey, thank for this very helpful tutorial. Concrete 5 is just so easy to extend.

    10th December 2011
    Anonymous
    Anonymous

    …the craftyside link to the file source seems to be down, would love to play with this idea, just installing C5 today for first day of experiments, could you let me know where else I can get the files?

    Many thanks
    ~ Sean

    1st February 2012
    Sean
    Sean

    Hi Sean, thanks for letting me know - I’ve found the new link and updated the post accordingly.

    1st February 2012
    Lukas White
    Lukas White

    Thanks Lukas : ) impressive speed of response, especially for a blog!

    1st February 2012
    Sean
    Sean

    Hi Lukas, I got up to "Applying the Template" and no template shows up in menu? instead it just says no template found and asks for block name.

    Checked directory structure a few times, double checked files, and don’t see any obvious silly errors I might have made : )

    Using latest build, 5.5.1 and wamp

    Not familiar enough with C5 yet to troubleshoot, presently use silverstripe and considering a migration. Is there any kind of refresh I might need to do to get the CMS to re-read the directory, or is it more likely some other error?

    Thanks
    ~ Sean

    3rd February 2012
    Sean
    Sean

    Hi Lukas, I have gone through your tutorial, but when I try to apply the templates nothing shows up just "the custome template availble", I am using c5.5.4.2.2.

    21st February 2012
    Joseph Myalla
    Joseph Myalla

    Ditto Sean and Joseph. I don’t see how C5 would even be aware of a custom template called "Craftyslide" with a capital C. I’m certain that I missed something. I’m squinting…

    24th May 2012
    Erik
    Erik

    Hi Lukas… im having the same problem as Sean…

    "I got up to "Applying the Template" and no template shows up in menu? instead it just says no template found and asks for block name."

    Can you point me out to a solution, please?

    30th May 2012
    Rui
    Rui

    We are looking to employ a new agency who have suggested that they would use "Concrete5" to re-design our data centre design association website (http://www.datacentredesign.org) to have a content management system to include a user account registration, add new pages, a tutorial section and blog. I was looking on sites that use Concrete5 and relevant blogs to see what other people were saying about using this platform. As we have no programming skills (beyond using Microsoft Frontpage) I would really appreciate other peoples comments on how easy they found it to use. Are there any specific advantages? - thanks.

    10th June 2012
    Ben (data centre design)
    Ben (data centre design)

    I am also facing the same problem as Sean : http://is.gd/ybGZDF It does not show any dropdown. Instead it says, "There are no custom templates available."

    I am using concrete5.5.2.1 an on WAMP.

    26th June 2012
    Jignesh
    Jignesh

    It does not show any dropdown. Instead it says, "There are no custom templates available."
    I am using concrete5.5.2.1 an on WAMP.
    Can you point me out to a solution, please?
    Thanks

    27th July 2012
    Rubi
    Rubi

Links and images are allowed, but please note that rel="nofollow" will be automactically appended to any links.