Symfony World blog is not maintained anymore. Check new sys.exit() programming blog.

symfony popup with jQuery thickbox - beginner's tutorial

Scene from "The Jetsons" by Hanna-Barbera (introduced in 1962)

Introducing jQuery thickbox pop-up


In this tutorial I will show you an easy way to create a thickbox using jQuery thickbox lib. At first, make sure you are familiar with the thickbox and take a look at the examples tab. We will create our pop-up feature basing on the iFramed Content section.


Install jQuery thickbox


The first thing you need to do is installing the software, of course. I want to make this tutorial as easy as possible, so just run the following commands from the project root directory:


wget http://jquery.com/demo/thickbox/thickbox-code/thickbox-compressed.js -O web/js/thickbox-compressed.js
wget http://jquery.com/demo/thickbox/thickbox-code/thickbox.css -O web/css/thickbox.css
wget http://jquery.com/src/jquery-latest.pack.js -O web/js/jquery-latest.pack.js
wget http://jquery.com/demo/thickbox/images/loadingAnimation.gif -O web/images/loadingAnimation.gif

After the files are downloaded, you need to make symfony include them into the generated output. One of the possible ways is to edit your application/config/view.yml file:


  stylesheets:    [ ..., thickbox.css ]
  javascripts:    [ ..., jquery-latest.pack.js, thickbox-compressed.js ]

The thickbox is already installed in your symfony project.


Basic usage


To make everything elegant, add 2 routes to your application/config/routing.yml file:


index_popup:
  url:   /popup
  param: { module: main, action: popup }
basic_popup:
  url:   /basic-popup
  param: { module: main, action: basicPopup }

The first route is just a demo action to demonstrate thickbox and you can the index_popup action with the following url:


http://local_sf_test/popup

The second route executes an action that shall be displayed inside the popup. Now we shall create the index_popup action inside the application/modules/main/actions/actions.class.php file:


/**
  * Executes popup action
  *
  * @param sfRequest A request object
  */
  public function executePopup(sfWebRequest )
  {
  }

and a link executing our basic popup - add the following code into your application/modules/main/templates/popupSuccess.php file:


<a class="thickbox" href="<?php echo url_for('@basic_popup') ?>?keepThis=true&TB_iframe=true&height=100&width=400">run basic popup!</a>

It's already working - if you press this link in the development mode, you'll get the symfony error Action "main/basicPopup" does not exist. - but generated in the thickbox. Now we're only left to create this action - create the file application/modules/main/templates/basicPopupSuccess.php file:


<h1>basic popup example</h1>

and the last thing - the basicPopup action inside the application/modules/main/actions/actions.class.php file:


/**
  * Executes basic popup action
  *
  * @param sfRequest A request object
  */
  public function executeBasicPopup(sfWebRequest )
  {
  }

The logic is very simple - only two things to be done:

  • The string ?keepThis=true&TB_iframe=true&height=100&width=400 is added to the end of the link's href attribute to pass some extra parameters to the thickbox. Those parameters can be easily modified, according to thickbox documentation.
  • The link has to have the CSS thickbox class
The screenshot below presents the output:




As we can see, the web debug toolbar is not fitting well here, therefore we may disable it by adding the following code to the executeBasicPopup action:


sfConfig::set('sf_web_debug', false);

This would display the popup without web debug no matter if the production or development controller is running:




Advanced usage

Above example could only display some static content. But it's not all that symfony thickbox integration can do - for example, you can embed symfony forms inside a popup. Create new action inside the application/modules/main/actions/actions.class.php file:


/**
  * Executes advanced popup action
  *
  * @param sfRequest A request object
  */
  public function executeAdvancedPopup(sfWebRequest $request)
  {
    sfConfig::set('sf_web_debug', false); // disable sf_web_debug
    $this->form = new ExampleForm(); // create the form object
 
    if ($request->isMethod('post'))
    {
      $this->form->bind($request->getParameter('example_form'));
      if ($this->form->isValid())
      {
        // do some business logic
        $this->getUser()->setFlash('notify', 'this message will be displayed inside the popup');
        return $this->renderPartial('main/message');
      }
    }
    return $this->renderPartial('example_partial');
  }

and a new route inside application/config/routing.yml file, corresponding to the new action:


advanced_popup:
  url:   /advanced-popup
  param: { module: main, action: advancedPopup }

update the popupSuccess.php file:


<a class="thickbox" href="<?php echo url_for('@basic_popup') ?>?keepThis=true&TB_iframe=true&height=100&width=400">run basic popup!</a>
<a class="thickbox" href="<?php echo url_for('@advanced_popup') ?>?keepThis=true&TB_iframe=true&height=100&width=400">run advanced popup!</a>

Now it's up to you to create a form class (the easiest way is to use a model form generated class) and display all its fields inside the _example_partial.php file:


<style>
#form {background: #d3e5f4; padding:5px 15px; color:#1f3037;}
/* some other CSS to be used by the popup form */
</style>

<div id="form">
  <form action="" method="post">
    <?php echo $form->renderHiddenFields() ?>
    <?php echo $form['example_field']->renderError() ?>
    <label class="label" for="example_form_example_field">example label</label>
    <?php echo $form['example_field']->render() ?>
    <input type="submit" value="submit" />
  </form>
</div>

The last thing to be created is the file to be used as the message partial, _message.php:


<span>example message</span>


Live app example


After clicking this button:




the following popup is displayed:




the form validation errors are displayed:




and finally the submission message is displayed:


Embedding videos in symfony projects using sfVideoPlugin

What does the plugin do?


sfVideoPlugin is a plugin created by a small international symfony developers team. It's destined to give an easy interface for online video embedding. The plugin uses flowplayer software and uses files with the flv extension.

It's so easy


sfVideoPlugin comes provided with few ways of embedding a flash video player inside you project.

including a partial

Once the plugin:publish-assets task has been run, flv files can be accessed from the web. Just include the video partial from the sfVideo module (enable it first, of course) passing one obligatory parameter - file (it's taken from the default flv directory):

include_partial('sfVideo/video', array('file' => '01.flv'));
Take a look at the plugin demo site.


video widget

Use the sfVideoWidget class inside your forms to display the player inside a form (you may use predefined sfVideoForm class which has only one widget). An example study case using video widget is uploading video files in the backend - user should have the opportunity to display the video file before publishing it online.


multiple player embedding

A simple parameter has been added to the partial mentioned above to enable displaying more than one video widget on one page. If the player parameter is not set when including a partial, the default value is "player" - you need to override the default value to display more than one player. Put the following code into an action:

$this->players = array(
  array('file' => '01.flv', 'player' => 'player01'),
  array('file' => '02.flv', 'player' => 'player02'),
  array('file' => '03.flv', 'player' => 'player03'),
);
and include the partial for each of defined players:
<?php foreach($players as $p): ?>
<?php include_partial('sfVideo/video', $p) ?>
<?php endforeach; ?>
Take a look at a live demo.


configuration

At now, there are four attributes defined in the app.yml file that are common for all players in the plugin. These are:

  • width
  • height
  • autoplay
  • autobuffering
The first two attributes take an integer value and the rest takes true/false values. Access them using:
sfConfig::get('app_video_autoplay')


contribution

Feel free to comment on the post and to contribute to develop the plugin.

Mail testing configuration in symfony

By default, the symfony mail delivery strategy is set to none. That means, that calling send method upon sfMailer object will perform no action.


Configuring mail delivery_strategy


All possible delivery strategies are described in the symfony docs. A good solution is to edit factories.yml in all application config directories and set production environment to realtime and development environment to single_address. The developer enters an E-mail address he's got access to, puts it in the delivery_address option and all mails sent from the project will be delivered to that address (so there's no worry that a customer/user will receive test E-mail). Put the following lines into factories.yml file to define mail configuration:

prod:
  mailer:
    param:
      delivery_strategy: realtime
dev:
  mailer:
    param:
      delivery_strategy: single_address
      delivery_address: your@address.com
Once we've set those values (even in the very beginning of a project development), we don't have to carry about mail configuration, hence symfony will carry out all mails to the correct addresses when working in the production environment.