Ask your Symfony questions! Pay money and get answers fast! (more info)

I'm looking for ideas to hack the way Symfony gets templates Symfony

  • SOLVED

We are working to open up this software so that anyone who wants can use it, but as a hosted service that lives on our servers. One person wrote to us and asked if Symfony Experts would ever be available in Russian. And right now, [[LINK href="http://codewi.se/signup_for_beta.php"]]on our waiting list[[/LINK]], there are people who want to offer French and Hebrew versions of [[LINK href="http://www.wpquestions.com/"]]WP Questions[[/LINK]].

So we have set up our software in the Rackspace cloud. The setup is like this:

Symfony core, installed from Pear:

/usr/share/php/symfony


A generic version of the software that powers Symfony Experts is at:

/home/cc/core

This folder has almost all project directories, except web:

apps

config

data

doc

lib

log

plugins

test

Each of our customers end up with a directory that they have FTP access to, which amounts to the web directory. In it are 4 folders:

css

js

images

uploads

PHP files do not execute inside of this folder. This is a security measure. We do not want our customers uploading PHP files and executing them.

However, I need for our customers to take the default templates (that you are looking at right now) and change them into French, Russian, Hebrew, etc.

I was thinking of creating a web form that would read the template and give our customers the chance to re-write it.

That raises 2 questions:

1.) Where should this template be saved?

2.) How to hack Symfony to look there?

Any suggestions.

Obviously I can not save the template back to /home/cc/core or every customer would overwrite the other customers. I am thinking of saving the templates in a file named after the customer, sort of like:

/home/cc/hi_I_am_a_customer/

/home/cc/and_i_am_a_customer/

And then possibly I could recreate a shadow version of the apps folder in there. But how to get Symfony to look in these folders for customized versions of templates? To take this question as an example, the default, that you are looking at, is:

apps/frontend/modules/question/templates/showSuccess.php

On our new server, a generic version of this template lives here:

/home/cc/core/apps/frontend/modules/question/templates/showSuccess.php

but how to get Symfony to look elsewhere for this template?

The server makes available an id for each of our customers:

getenv(‘TMA_USER_ID’))

So I was thinking I could use this to point Symfony toward some starting point, for looking for the templates. But then I need to know where to set that starting point.

[UPDATE]

Having thought about it, I realize,this would work for me as the kind of check that I would want to have, in the templates that can be overridden.

public function checkForCustomTemplate($request) {
$application = $this->getContext()->getConfiguration()->getApplication();
$module = $request->getParameter('module');
$action = $request->getParameter('action');

$customTemplateName = $application . '_' . $module . '_' . $action;
$path = '/home/' . getenv('TMA_USER_ID') . '/templates/';

if (file_exists($path.$customTemplateName)) {
// something magic happens here, and Symfony knows to use this template
}
}



But where is the magic bit? Since this file lives outside of the normal Symfony project, I need to override setTemplate(), I guess? Figure out how to tell it to look in a particular place?

I don't suppose there is simple array of directories that Symfony checks, that I could edit?


[UPDATE]

In File: view/sfPHPView.class.php there is the renderFile() method, which potentially I could hack, though it is used for every partial and template in the system, and it seems like the sfContext won't get the request object when I'm in there, which makes it difficult to figure out the action and module.

So I'm open to ideas about better places I might make the changes that I'd like to make.

Answers (2)

2010-11-08

Joshua Estes answers:

Why not just use the built in i18n and l10n stuff? If you use doctrine they even have an i18n behavior.


Lawrence Krubner comments:

That would be the way to go if language was the only concern. Language is something obvious I can point to right now, but in fact, long term, we want our customers to be free to re-do the templates entirely.


Joshua Estes comments:

Yes, I would agree, I just skimmed over it at first. So basically it looks like i18n and l10n may not come into play here.

Right off hand I could think of allowing like a template folder. What may be the best route to go is to not give FTP access, but instead create a backend interface where users can upload/edit css and js files, upload images, and edit the template files. I would think something like the WP theme editor would work.

I have been looking into using a type a 'theme' system on some of my projects, but haven't got around to really playing with it and seeing what the different ways are.

Another way to do it is to do something like this http://snippets.symfony-project.org/snippet/115 as well as modify the router like this http://www.symfony-project.org/more-with-symfony/1_4/en/02-Advanced-Routing

There's various different ways you can go about this. Try a few and see what works and what would be the easiest for your customers. If it's easier for your customers to just FTP some html/css/images/js files then go that route. As for the directory structure, I would just add another folder called 'templates' and within that directory you would have folders named after the modules you have.

Doing what you want is going to take some time, but I'm sure it can be done.


Lawrence Krubner comments:

The article http://www.symfony-project.org/more-with-symfony/1_4/en/02-Advanced-Routing is fantastic. Thank you for pointing me to that.

2010-11-08

Nate Flink answers:

From what you've described, I don't think it is necessary to hack apart symfony in that way.

I would suggest setting this up using symfony's plugins construct. Messing with the folder layout has the disadvantage of potentially breaking with sf new versions, as well as, being a lot of work to do, and sort of breaking mvc.

The advantages might be to be able to use the automatic overriding of forms, templates, and actions. I have found that the symfony plugin architecture is really useful for extending a project to use a database core, and library core, where it is needed to have many different apps that support different requirements for different vendors.

For each customer or vendor, you can create a new application that uses your plugin. All the models, forms, actions, and templates (and other stuff) can be set up with defaults. When it comes time to add a version for Hebrew or Russian, you can over ride the templates and actions to suit the requirements. This also makes the problem of setting up routes easier. To set up urls to each different version of the app, it is possible to write condition checks in the index.php controller to route to the other app controllers, based on the given url.

Essentially this is a kind of "hydra design", where each different head is supported by a common body.

To solve the problem of how to deal with stuff in the /web folder, I have had good luck in the past by creating a subfolder that is named for each app, with the corresponding js css images, etc. folders inside that. It's not hard to add that extra token to asset paths in the code, and then you've got an encapsulated mechanism for giving your customers access to the decorators, the js, css, etc. for their version of the app. You can easily restrict FTP, sFTP, or a home brewed file access script to a specific folder, and/or restricted set of file types.


Lawrence Krubner comments:

Nate, these are good ideas, but I think I would have problems automating it. If we get 10,000 customers, all with FTP access, I'm not sure how to lock them all down to a given folder with your setup. I think the solution has to live outside of the customer account.