Archive

Posts Tagged ‘Symfony’

Symfony Form: Extract Values

September 8th, 2011 2 comments

I had to look deep into Symfony 1.4 code this morning as I was trying to get a field’s value. Form values come from different sources: default values, record values (when editing, for example), original POST values and clean POST values. So when is each available and how do we get it?
Read more…

Tags: ,

Symfony task “default” context

May 16th, 2011 No comments

When creating Symfony 1.4 CLI tasks, I stumbled upon an error message:

The "default" context does not exist.

After searching some old forums, I found a solution. Before you access any Doctrine class, you mus first bootstrap your context correctly. Here is an example:

$config = ProjectConfiguration::getApplicationConfiguration(
  'frontend',
  'dev',
   false
);
sfContext::createInstance($config);

              
The application name and the environment can come from CLI options. More on Doctrine tasks (I could only find 1.2 equivalent): http://www.symfony-project.org/cookbook/1_2/en/tasks
Tags: ,

Integrating Markdown with Symfony

April 25th, 2011 No comments

Context

I needed to create a number of static help pages in three languages in a Symfony 1.4 application. Using the XLIFF translation files seemed absurd, since I knew that I will include a lot of HTML. As you know, XLIFF translation files are XML, and so any HTML needs to be converted to entities, which makes maintenance a pain. Also, loading the entire manual’s XLIFF when requesting a single page is not optimal. And so, I decided to create partials using the following structure: _docs/{lang}/{title}.php. This method would organize my pages nicely and will only load what is needed.

Then, I remembered that we were planning to hire a technical writer for the rest of the manual. I wanted to make his life as easy as possible and the source files easy to read for everyone. I went that far; I might as well write the manual using Markdown. Because Symfony can cache static pages, Markdown will only parse each page once. I did not have to worry about performance! Here is how to quickly add Markdown to your Symfony 1.4 application.

Solution

  1. Download the paser
  2. Copy the PHP file to your lib/helper or apps/{application}/lib/helper directory
  3. Rename the file to MarkdownHelper.php
  4. In your controller, load the Partial helper: $this->getContext()->getConfiguration()->loadHelpers(array(‘Partial’));
  5. Load your partial: $this->content = get_partial(‘{module}/{partial}’);
  6. In your template, load the Markdown helper:
  7. Parse and output:

Notes

Steps 4 and 5 can also be achieved on the template level as well.

The reason for calling the Markdown helper in the template and not in the action is due to Symfony’s output escaper (and also because presentation logic belongs in the View). By default, Symfony converts all HTML tags to entities, which is great for security, in case the input comes from an untrusted source. Had we parsed with Markdown at the controller level, you would have seen HTML tags in your browser. If, for any reason, you still wish to parse at the controller level, make sure to output using this code: $sf_data->getRaw(‘content’);

Here is a link to short and comprehensive Markdown Syntax Documentation.

Tags: ,

Symfony – subfolders for partials

February 19th, 2011 10 comments

Symfony 1.2 – 1.4 expects all partials to follow this convention: templates/_partial.php

What happens when you need to organize your partials in subfolder? I tried a number of “Symfunky” avenues. Feel free to skip to the solution.

Avenues Explored

I first try the call the include_partial helper with “subfolder/partial”, but that results in Symfony attempting to find the partial in the “subfolder” module.

Alright, so I try “module/subfolder/partial”, but that results in Symfony looking for “_subfolder/partial” because it simply split at the first backslash. I don’t blame the framework developers: I am trying to do something it was not meant to do.

So now I realize that we can set any template from an action using $this->setTemplate(’subfolder/_partial’). Since actions are NOT partials by definition, I decide to use a component. Unfortunately the component doesn’t allow the developer to override templates.

I am starting to feel that the framework mocks me. So this is how you wanna play it, huh? I will override your sfView class, load it in factories.yml, and there’s nothing you can do about it (insert diabolical laughter)! But then, after almost half an hour, I realize that I’m trying to make it too elegant for something so basic as concatenating a few strings.

Solution

The solution ended up ridiculously simple and does not risk breaking any existing code.

1. Copy get_partial() helper with an extra param: get_partial_subfolder($templateName, $vars = array(), $subfolder)
2. Edit the line that concatenates the file name: $actionName = $subfolder.’/_’.$templateName; (instead of ‘_’.$templateName)

There you go, no more headaches. Just remember to use “echo get_partial()” instead of “include_partial()” unless you want to override that helper as well. If you are unsure how to create custom helpers, see here under Adding Your Own Helpers: http://www.symfony-project.org/book/1_2/07-Inside-the-View-Layer

Tags: ,

Doctrine Translation in leftJoin()

April 24th, 2010 No comments

If you use Doctrine, then you probably know how lazy loading can hurt your performance. I carefully craft every query to everything that I need in one shot, but only what I need. One thing that evaded me at first was the i18n part.

Model Relationships

I am pleased with the way Doctrine + symfony magically creates all my models and database tables with i18n support. All my relationship names are explicitly defined in the schema.yml file. So, if I want to get all products in a transaction, I can access it via $transaction->Products. When crafting a query, I would say ->leftJoin(‘t.Products’) to make sure to load all the products at the same time as the transaction, potentially saving hundreds of queries later.

I18n

Since the i18n relationship is defined in a special way in schema.yml, without specifying a relationship name, I wasn’t sure how to write my Left Join. I looked up the Base[ClassName].class.php file but did not find anything useful. After analyzing all the parent classes, I found it: Translation. It might have seem obvious since the tables are names product_translation, but that element eluded me and I did not find anything in the documentation at the time regarding this.

Other uses

Now that I can get my product names with ->leftJoin(‘p.Translation’), I cut the number of queries in at least two. Knowing the Translation relationship can have other uses, like counting the number of translations in your code and warning the user about missing translations (no product name in French!). I can also use the Translation relationship to make my search-engine friendly URLs multilingual. I can write about this last one in another post if I get such a request.

The uses for the Translation relationship are infinite!

Tags: , ,