July 29, 2006

Approximating Master Pages in PHP

Most sites on the Internet have common design elements that do not change from page to page. Usually, only content or minor navigational cues vary. To handle the unchanging aspects, developers have often relied on server-side includes - dividing regions like headers, side navigations and footers into separate files.

But now with the advent of ASP.NET 2.0 Master Pages offer a more complete templating alternative. With Master Pages an entire template common to the site is stored in one file with a .master extension. Developers add a ContentPlaceHolder control inside a Master Page to indicate where they would like their page specific content to appear. Then one or more Web Forms may be set up to automatically dress themselves with the shared visual components defined in the Master Page.

So is it possible to make PHP emulate this behavior? To some degree, yes, with output buffering and one server-side include file that represents the "Master Page." Lets say we are aiming to create our HTML by combining this template file and a content file (we'll call these master.php and index.php, respectfully). Our simplified example will aim to achieve the following end result:

The template that will act as our "Master Page" will need to contain all aspects of the design labeled "Template Specific." Since no such control like the ContentPlaceHolder exists, we will use PHP variables to indicate where we would like our page specific content to appear.

I personally these days prefer smarty which compiles itself to php code anyway so there's no slowdown except the initial compile (and, granted, two modification time checks on the template file and the php code generated from the template, but that's nothing) and you get on the plus side a nice seperation of content and code.

I agree I really like the concept. At work I use ASP.net master pages, and I really wished there was some sort of method for php. I saw another blog about how to use a template, but each section was an include file. I'm pretty sure there is some sort of security flaw using include('$page.php'), but this examples method doesn't seem to have that problem and it's very easy to implement.

A very simple and effective solution, specially when you've been coding ASP.NET websites and then you face PHP again and don't want to end up using Dreamweaver's propietary template system (which works great but I prefer to write PHP with a better code editor).

BRILLIANT!!!!I work in a Microsoft shop and am sometimes befuddled by the burden of .NET. This is clear and simple, and worked on the first attempt after popping up almost in the #1 position on Google.Thank you thank you thank you.

I'm trying to get this to work and am having some really weird issues. Mainly, about half of the "head" elements (the "link" and "script" tags) are being put in the body instead of staying in the head. Anyone else have this problem? I've made a detailed post here, for anyone that cares to look. Thanks!

But what the problem occurs is that when "include'master.php'" is included it includes my Paging result in Master page's "Table Data Tag" second and considers it as new page and paste it is new page under "Table Data Tag". So please help me.

Please help because I want to implement more AJAX functionalities in my Website.

I originally designed my newest site like this, but it has some downfalls. First: If you have an include file that needs to be included by all pages, it makes sense to include it in the master page (i.e. something like Doctrine, nusoap, xajax, etc). Because the master page is included by the content pages at the end of the file, the classes provided by the global includes will not be accessible in the content pages, requiring the content pages to include the files. This become cumbersome and in the end requires nearly twice as many includes (the way I had it set up at least - one ajax include, one normal php include - repeated global includes). Second: When I changed my site's layout to instead include a header and a footer in each content page (which cut the number of pages on my site nearly in half) I noticed an enormous load decrease on my larger data-driven pages. If you have a large data-driven page, the server has to buffer the data on each load. On large, heavy traffic pages this causes a huge performance hit. My suggestion is to include a header file and a footer file. In the header file you can have a variable to control css includes and js includes (which can still be output in the head section), as well as additional onload functions, etc. If you think about it, including a header and a footer file in each content page actually decreases the amount of code in each content page by a few lines. I would research this "master page" solution before diving in and designing a whole site this way, not that a page can't be done this way.

This is a great article and easy to understand. However, being new to PHP and trying to work through your example I'm getting an error: syntax error, unexpected ' ob_start' on line 3 of your index.php. Is there some unmentioned step that needs to be done to use the output buffer routines? Please advise.