开发者

Templating in PHP done right ... how?

Some years ago I created a small website in PHP that now has grown and as you can probably guess it's quite a bit of a mess. Although I do have a separate template that does the final outputing of the html, I still end up having do handle a lot of the html in the 'business logic' part of the code.

My main problem is that the page contains various widgets (like 'latest entries', ads, etc.) that change from page to page开发者_StackOverflow中文版 and thus their html-(template-)code can't be hardcoded into the template. In fact even the main-content-container is a widget since the page-structure (or layout) is always the same.

So I end up having an array with $templateData['mainContent'], $templateData['widget1'], $templateData['widget2'], etc. that is generated in the business-logic part of the code.

How do I solve this?

Having looked around for a while there seem to be 2 ways to solve this:

  1. The obvious way would be to use a dedicated template language with inheritance and includes like django does, but given how complex these languages are I'm not really willing to learn yet another one of them. Also what I noticed during the time I spend with django was that it's not particulary fast (especially because it tempts one to use that templating for css and javascript too).

  2. The other option would be to use the templating features that PHP itself provides. But that would mean that every widget would have its own php-template and would generate its html-code by including the template-file and trap the result using output buffering. Is this a good idea? Since I still end up with HTML inside of the variables inside the logic-part. Also, doesn't this abuse output buffering for something that it wasn't intended for? And what about performance? (where is the buffer that I'm writing/reading/flushing from? How expensive are calls to ob_* functions?)

From what I've seen there are advocates for both variants. Personally I like option 2 more (since it's sort of what I'm already doing), but the html-in-variables feels very wrong and I doubt wether I would be solving anything this way.

Is there maybe another option? How have you solved this problem?


Why not to let each widget just include it's template?
So, you will have to just call widgets from your main template.


I had this problem before and I had almost the same ideas/questions that you currently have. I obliged myself to learn a template language. Enter Twig a lightweight template language that is influenced by Django's template language. It has a very small footprint, almost invisible in terms of memory usage.

Give yourself some time to get used to it and then decide if you want it or not.


assign those nice arrays to smarty and learn to iterate them on the tpl files. it's easier than it seems. when you need to include many times the same piece of html/php you just re include it.

http://www.smarty.net/

is smarty fast and reliable? yes


One idea would be to create template-driven / view-driven pages accessing a web service or an API serving all the data you need.

You could link URLs to templates, and the templates call data retrieval functions either via web service (AJAX style) or statically.

The business logic part is then limited to processing of inputs and preparing generic retrieval and provide mechanisms for e.g. filtering or sorting, while the templates determine how to filter, how to sort or how to paginate etc.

I suggest that you use a proper object-relational mapping (ORM) framework / ActiveRecord pattern (see here on StackOverflow, or in Wikipedia) that allows you to use generic retrieval objects that can be re-configured by the template to suit its needs (such as the aforementioned filtering and sorting).

The actual retrieval would then be done in the template when needed by calling a special method like find(), load() or similar on the retrieval objects.

EDIT:
Regarding template frameworks as others suggested, I do not like them very much as they often duplicate functionality already found in PHP, reinventing the wheel by adding yet another parser layer; a benefit you get from any decent template framework however is caching (there may be some PHP-based templating engines out there that also support caching).


Multiple options

There are several ways to do it.

Here's a couple of strategies worth considering :

  • Use plain PHP views that you encapsulate (include) in a method of a PHP object. This is how CakePHP implements its views.

  • Load a HTML file with placeholders like <% %> as plain text and use regex to replace the content

  • Load an HTML file and parse it as XML or HTML. Then, you can use something like Symfony's CssSelector component to add, remove or replace content the same way you'd do it with jQuery. Then, render it back to plain text and echo it.

  • Use one of the following popular template engines :

    • Smarty

    • Twig

    • Latte

    • Mustache

  • ...


Best option?

Which option is best? I guess it depends on your use case :

  • Plain PHP will always give you the best performance, but it's also the least readable option.

  • If you like to go through your HTML code the same way you do things with jQuery, you might want to use a library like DOM-Query.

  • If you're looking for a well-tested templating engine that can be used both in backend and frontend, Mustache is the way to go!

  • ...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜