Photon - Gallery Plugin for Croogo CMS

What is Photon?

Photon Gallery is a gallery and photomanagement plugin for Croogo CMS, originally based on Edinei L. Cipriani's gallery plugin. However it offers much more features and capabilities - it is heavily extended. Photon's administration is AJAX-powered and integrates flawlessly into your existing Croogo install. A new Tab is added to your nodes which allows you to upload pictures via Ajax - those pictures are directly related to that specific node. Doing so, Photon features four different preconfigured ways of displaying your photos: either in an Image Replacement gallery, in a Slider gallery, in JQuery Popeye gallery or just as single images. A seperate set of administration-views allows you to have full control over all your gallery stuff.

Once again, to point out the most special feature, the so called "NodeAlbum"-feature: For each node a specific album is automatically created. Thus, you can upload photos directly when creating nodes!


  1. Install this plugin via the extension management of Croogo or upload the folder "photon" to /app/plugins
  2. Activate the plugin: the tables will be created and initial settings be saved
  3. Add new albums & upload photos
  4. Enjoy (hopefully) :)

You can access the gallery via yoururl.tld/gallery. If you want to display photos or galleries inside your nodes, just put code like this at the desired location in your node: [Gallery:slug] [Popeye:slug] [Slider:slug] [Image:id]

When running your Croogo with markdown, please make sure you first activate markdown, and photon afterwards. Otherwise your galleries wont be rendered.

Thanks to...

Big thanks to "mherb" (https://github.com/mherb) for fixing tons of bugs and adding nice features such as single picture management!

Download: Photon at GitHub

Croogo: How to pass data from a plugin to an existing admin view

Hi fellow bakers, this is meant to be a tiny tutorial on how to pass data from your own plugin to an existing admin view, e.g. your plugin adds an additional tab to the Users edit view, and you want to provide the data displayed in that tab.

I've been searching for the answer on how to achieve this myself for months, and I couldn't believe how easy it actually was. I'm gonna show you how to do that right now.

What you need

You need an element that shall serve as an admin tab, and you need to tell Croogo that it indeed is. I added a new tab to the User admin add and User admin edit views inside the plugins bootstrap file.

Croogo::hookAdminTab('Users/adminadd', 'Pluginname', 'pluginfolder.adminuserextended');
Croogo::hookAdminTab('Users/adminedit', 'Pluginname', 'pluginfolder.adminuserextended');

What does this element contain?

Everything you want to be displayed inside that tab. For testing purposes I think the following piece of cake, er code is good enough:

data); ?>
This will display all data that is available to be displayed - really handy in combination with the form helper!

Now that's just the preparation, now we're going into it. We need a behavior, and we need to bind that behavior to an existing model, which is done inside the plugin bootstrap as well:

Croogo::hookBehavior('User', 'Pluginname.ExtendedUser', array(
    'relationship' => array(
        'hasMany' => array(
            'Customfield' => array(
                'className' => 'Pluginname.Customfield',
                'foreignKey' => 'Pluginname.User_id',
                'conditions' => array('Customfield.status' => 1),

Here you can see how you can bind a behavior, which is part of your plugin, to an existing model provided by Croogo. But that's by far not all: As the third argument an array containing a relationship (this is not limited to just one association, you can set up as many as you want to) is supplied. This array is passed to the behavior and actually serves as an array containing custom data for your personal needs inside the behavior. This also means, that until now, nothing would happen. There is no functionality implemented in your behavior that could handle this tiny array containing the definition of a relationship. Luckily, we can do that ;)

And it might look like this:

<?php class ExtendedUserBehavior extends ModelBehavior {

function setup(&$model, $config = array()) {
    //Merging the specified (or not specified) config array with an array containing default values
    $config = Set::merge(array(
        'relationship' => false,
        'joins' => false,
        'enabled' => true,
        ), $config);
    //Each Model($model->alias) gets its own key containing the specific config array
    $this->settings[$model->alias] = $config;
    //Now let's setup any desired relationships
    $this->_setupRelationships($model, $config);

function _setupRelationships(&$model, $config = array()) {
    if (!empty($this->settings[$model->alias]['relationship'])) {
        //Here we add the specified relationship to our model ON THE FLY
        $model->bindModel($config['relationship'], false);
        //To make sure we really get all the desired data, we need to set the recursive level!
        //This really drove me mad, don't forget to adapt this according to your needs
        $model->recursive = 2;

function beforeFind(&$model, $query) {
    //Needs to be done!
    return $query;


function afterFind(&$model, $results, $primary) {
    return $results;
    //Here we just merge all available fields with the ones the user already has filled out, and return that as a new array


function beforeSave(&$model, $query) {
    //Since save() wont save any associated data, we got to do this on our own
    $temp_data = $model->data['UsersExtendedField'];
    return $query;

} ?>

What this behavior actually does is pretty simple. It fetches the array 'relationships' out of the configuration array specified in the plugin bootstrap and binds those relationships on the fly to the model. Easy, huh?!