Symfony Partials: Accessing Raw Data defined in an Action

Sometimes we need to pass some message from the action to a partial via template. If this message only contains plain text there is no problem, we simply define the property in the action, and in the template we pass it to the partial, like this:

In the action:

// modules/mymodule/actions/actions.class.php
class mymoduleActions extends sfActions
{
  public function executeShow(sfWebRequest $request)
  {
    $this->msg = "My plain info message";
  }
}

In the template:

<!-- modules/mymodule/templates/showSuccess.php -->
<hr />
<h1>My Module</h1>
<?php include_partial('mypartial', array('msg' => $msg)); ?>
<hr />

And in the partial:

<!-- modules/mymodule/templates/_mypartial.php -->
<p><? echo $msg ?></p>

The problem comes when we include a little of html in the message, for example, lets change the action:

class mymoduleActions extends sfActions
{
  public function executeShow(sfWebRequest $request) 
  {
    $this->msg = "My <b>html</b> info message";
  }
}

Now, if we leave the template and the partial unchanged, you get this in the navigator:


My Module

My &lt;b&gt;html&lt;/b&gt; info message


Ok, it seems that we forgot to get raw data, so lets change the template:

<!-- modules/mymodule/templates/showSuccess.php -->
<hr />
<h1>My Module</h1>
<?php include_partial('mypartial', array('msg' => $sf_data->getRaw($msg))) ?>
<hr />

And now the result is:


My Module

My <b>html</b> info message


That is a little better, but it is not still the desired result. To get it, we have to also change the partial:

<!-- modules/mymodule/templates/_mypartial.php -->
<p><? echo $sf_data->getRaw($msg) ?></p>

And finally we get what we wanted:


My Module

My html info message


The conclusion is that if we want to send raw data from the action to the partial, we will have to raw it in both, the template and the partial.

Setting a value to a hidden form symfony field

The case

Sometimes, when creating a new object, we need to give a default value to a specific field but we don’t want this field to be visible in the form.
A tipical example would it be a blog -> post relationship. Where we want the blog_id field to be set automatically but we want it to be hidden.

Blog->Post

Blog->Post

The mistake

When creating a new post for a blog, we do not want the blog_id field to be visible, so we typically go to PostForm.class.php and unset the field blog_id:

//myproject/lib/form/PostForm.class.form
class PostForm extends BasePostForm
{
  public function configure()
  {
    unset( $this['blog_id'] );
  }
}

Then, we edit the action class and set a default value for the blog_id field:

// mypoject/modules/post/actions/actions.class.php
class postActions extends sfActions
{
  public function executeNew(sfWebRequest $request)
  {  
    // create the form
    $form = new PostForm();

    // get blog_id parameter from the request
    // and set the default value
    $form->setDefault("blog_id", $request->getParameter('blog_id') );
    
    $this->form = $form;
  }
  //... rest of actions here ...
}

Finally, when we try to create a new post, we realize that the blog_id has not been set correctly.

The solution

Instead of unsetting the blog_id field, we have to change its widget to a sfWidgetFormInputHidden:

//PostForm.class.form
class PostForm extends BasePostForm
{
  public function configure()
  {
    // the wrong way in this case
    // unset( $this['blog_id'] );

    // the right way in this case
    $this->widgetSchema['blog_id'] = new sfWidgetFormInputHidden();
  }
}

This way the field blog_id remains hidden but do exists in the form, so the setDefault method works correctly.