SkillAgentSearch skills...

GjPositionsPlugin

[symfony 1.4 plugin] adds a composition workflow to your admin module that allows the user to compose a canvas from components/partials and manually assign any type of content to them

Install / Use

/learn @caefer/GjPositionsPlugin
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

gjPositionsPlugin - visual page composition

About

Many websites - especially those driven by editorial content - have one or more aggregation pages like home pages, index pages, category pages and so on. Their purpose is to aggregate the underlying contents often with the latest contents on top but also you often find contents listed manually by an editor using some kind of administration tool.

The difficulty is that the underlying contents can be of various types like articles, galleries, videos, quizes, etc. .. Most of these contents will have their own custom visualisation as i.e. a gallery will render differently than an article.

gjPositionsPlugin provides means to compose such aggregation pages from a flexible list of design elements such as slideshows or teasers and to manually assign any type of content to them.

This functionality is provided in form of admin modules that you can generate for any of your models (in case a home page and an index page are not the same).

Installation

Currently you can only get this plugin from GitHub. It is still highly experimental and will change.

$ cd plugins
$ git clone git://github.com/caefer/gjPositionsPlugin.git

This plugin depends on my fork of sfDoctrineDynamicFormRelationsPlugin which is originally developed by Kris Wallsmith. A pull request is issued already so hopefully both versions can be merged again.

$ cd plugins
$ git clone git://github.com/caefer/sfDoctrineDynamicFormRelationsPlugin.git

Then edit your ProjectConfiguration class and enable the plugins.

<?php

require_once dirname(__FILE__).'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';
sfCoreAutoload::register();

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    $this->enablePlugins('sfDoctrinePlugin');
    $this->enablePlugins('gjPositionsPlugin');
    $this->enablePlugins('sfDoctrineDynamicFormRelationsPlugin');
  }
}

Next you need to publish the plugins assets by running the following.

$ php symfony plugin:publish-assets

Additional Requirements

Please note that gjPositionsPlugin requires jQuery and jQuery UI. It was tested with jQuery version 1.4.2 (jquery-1.4.2.min.js) and jQuery UI version 1.8.6 (jquery-ui-1.8.6.min.js). Both files have to be loaded for the admin module to work!

Term Definition

<dl> <dt>Composition Canvas</dt> <dd>The <em>Composition Canvas</em> is a space inside the generated admin module. You can drop multiple <em>Design Elements</em> onto it, reorder or delete them. When rendering you record you can access these design elments through a relation and render them accordingly.</dd> <dt>Design Element</dt> <dd>A <em>Design Element</em> is a partial or component plus some settings in your app.yml. <em>DesignElements</em> are developed by yourself according to your requirements. <em>Design Elements</em> can be static (partials) or dynamic (components) and they can be parameterized with settings you define and they can have <em>Content Elements</em> assigned to them.</dd> <dt>Content Element</dt> <dd><em>Content Elements</em> are placeholders for a single record of any of your models. They represent the relation between a content record and a <em>Design Element</em>.</dd> </dl>

Usage

To get started you have to follow these following steps.

1. Make any one of your models act as a composition

Assuming you have a model called Homepage you simply have to add the gjCompositionCanvas behaviour to its schema definition.

Homepage:
  actAs:
    Timestampable:        ~
    gjCompositionCanvas:  ~
  columns:
    title:                string(255)
    headline:             string(255)
...

2. Develop as many Design Elements as you want

This one is totally up to you! A Design Element can be anything from a simple partial template to a complex component implementing business logic. The only thing you have to regard is that the only the following parameters will be passed to your partial/component:

  1. params is an array of settings saved for this Design Element. You will see in a moment how this can be done.
  2. subject is the instance of your composition model (i.e. Homepage) that this Design Element is assigned to.
  3. contents is a list of Content Elements that were manually assigned to the Design Element.

3. Configure your Design Elements to be used in the generated admin module

Lets assume you wrote a simple partial yourmodule/banner that renders a bit of HTML and contains no other PHP (more complex examples will follow later in this document).

all:
  gjPositionsPlugin:
    design_elements:
      banner:
        description:      "This is a simple banner"
        applies_to:       [ Homepage ]
        include:          "yourmodule/banner"
        accept:           ~
        params:           ~

With these settings you defined a Design Element called banner that can be assigned to a Homepage and will render the partial yourmodule/banner.

If you want to provide a little business logic you may prefer a component. Here is what the settings would look like.

all:
  gjPositionsPlugin:
    design_elements:
      banner:
        description:      "This is a simple banner"
        applies_to:       [ Homepage ]
        include:          [ yourmodule, banner ] // for a component you provide an array
        accept:           ~
        params:           ~

The other settings will be explained further on.

4. Generate your admin module using the composition theme

You simply generate an admin module for your Homepage model with the symfony/doctrine admin generator.

$ php symfony doctrine:generate-admin --theme=composition frontend Homepage

The only difference is that you use the composition theme provided by gjPositionsPlugin.

Now browse to your freshly generated admin module and take a look. You will see that the edit view of your admin module consists of three columns.

  • The left one displays the form for your `Homepage and also holds the Composition Canvas.
  • The center column displays all Design Elements that can be applied to a Homepage
  • The left column displays Content Elements which we haven not used so far.

5. Render Design Elements assigned to your Homepage

You don't have to change anything in your action so it might look as simple as this.

public function executeIndex(sfWebRequest $request)
{
  $id = $request->getParameter('id');
  $this->forward404unless($id);
  $this->homepage = Doctrine_Core::getTable('Homepage')->find($id);
}

The interesting part happens in the template.

<?php use_helper('gjPositions') ?>
...
<?php foreach($page['DesignElements'] as $name => $designElement): ?>
  <?php include_design_element($designElement); ?>
<?php endforeach; ?>
...

Through the DesingElements relation you can simply iterate of all Design Elements that you have assigned to this Homepage in the admin module. The gjPositionsHelperprovides a helper function include_design_element() which merges the Design Element with the settings from your app.yml and returns either an include_partial() or include_component().


And that's all there is to it to be able to compose a Homepage from various Design Elements.

Advanced Usage

But of course there is more to it!

1. Limiting the use of Desing Elements to specific models

If make heavy use of gjPositionsPlugin and turned multiple models into Composition Canvases you might find the situation that some Design Elements are not suitable for all Composition Canvases.

I.e. a contactform might be only suitable for a Sidebarbut not for a Homepage.

Taking the above example the following settings will limit the use of a banner to only Homepages and Sidebars.

all:
  gjPositionsPlugin:
    design_elements:
      banner:
        description:      "This is a simple banner"
        applies_to:       [ Homepage, Sidebar ]
        include:          [ yourmodule, banner ]
        accept:           ~
        params:           ~

2. Parameterizing Desing Elements

With all the above you would be able to implement for example a Design Element that displays the latest articles that have been created in your database. This would be a simple component that fetches a number of articles from the database and renders them in a list in its partial template.

You can use this one Design Element on all your Homepages. But you might want to filter the articles for a section homepage to show only those related to this section? Or you might want to list the latest 20 articles on your homepage but only 10 on your section homepage?

For this you can configure parameters on Design Elements like the following.

all:
  gjPositionsPlugin:
    design_elements:
      latestArticles:
        description:      "Shows the latest articles"
        applies_to:       [ Homepage ]
        include:          [ article, latest ]
        accept:           ~
        params:
          number:         { type: text, default: "5" }
          section_id:     { type: text, default: false }

These above settings will result in two more input fields on the Design Element in your admin module. They can be edited per assignation.

All types of <input/> tags are available but probably only a few like text, checkbox or radio make sense.

The values of these parameters will be available in your component and/or partial.

// in your component
...
$this->articles = Doctrine_Query::create()
  ->from('Article a')
  ->orderBy('a.created_at DESC')
  ->limit($this->params['number'])
  ->execute();
...

// in your partial
View on GitHub
GitHub Stars16
CategoryContent
Updated1y ago
Forks7

Languages

PHP

Security Score

75/100

Audited on May 2, 2024

No findings