Textpattern tips, tutorials and code snippets

Static Textpattern Forms and Pages

When I started work on redesigning my site, I also made the switch from WordPress to Textpattern. There was one thing that I really started to miss while developing the site — files for templates. WordPress had made this so easy in its theming system, which uses PHP files, thus allowing the use of an external text editor. Instead, Textpattern forces you to use a textarea in the admin interface, and saves the markup in a database. Since I like to have syntax highlighting and the ability to quickly edit multiple templates at once, I decided to create a little workaround to allow me to use files for both page and form templates.

Warning & Disclaimer

Before I begin, if you are allergic to looking at source code I recommend you look away now. Still here? Then let’s begin, and don’t say I didn’t warn you.

The modifications made here are to the Textpattern 4.2.0 core library files, as such any updates to Textpattern will require you to repeat this process. While unlikely (I run this on all my Textpattern installations), I take no responsibility if your install breaks as a result of making these changes. If you would like a quick and easy method of having static page files only (ie: not forms), then please read this TXP Tip by Jon Hicks which explains how to achieve this with a lot less effort.

Getting started

This guide is based on creating the template folder outside of your textpattern folder at the same level as it. If you would like your templates somewhere else, modify the location in each case below. You will also need to enable ‘Allow PHP in pages?’ in Advanced Preferences of the Admin tab, if you haven’t already.

Pages

First, the templates for pages. In the textpattern folder, open the file publish.php. On line 482 is the start of the textpattern() function (do a search for ‘function textpattern’ in your favourite text editor). We want to edit this function to try and import a file, should it exist, before looking in the databse for the page HTML.

Replace lines 496 to 498 with the code shown in the Gist below — start copying from $html. The … indicates that there is more code not shown, and the function textpattern() is to show what function you are editing in the file.

<?php
...
function textpattern()
{
	...
        $html = @file_get_contents(txpath.'/../templates/pages/'.doSlash($pretext['page']).'.php');
	if (!$html) $html = safe_field('user_html','txp_page',"name='".doSlash($pretext['page'])."'");
	if (!$html)
		txp_die(gTxt('unknown_section'), '404');
...
?>

Textpattern will now look for page templates in templates/pages/ folder. Make sure to set up your sections and corresponding page templates as you want them. Create a new file in the pages folder with the same name as the page template you wish to use: default.php, for example, if you wish to overwrite the default page.

Forms

Following the same process as for pages above, open the file textpattern/lib/txplib_misc.php. On line 1589 you will find function fetch_form($name) (do a search for ‘function fetch_form’ in your favourite text editor). Replace this function with the one below:

<?php
...
function fetch_form($name)
{
	static $forms = array();
	if (isset($forms[$name]))
		$f = $forms[$name];
	else {	  
	  $row = @file_get_contents(txpath.'/../templates/forms/'.doSlash($name).'.php');
		if (!$row) { 
		  $row = safe_row('Form', 'txp_form',"name='".doSlash($name)."'");
			if (!$row) {
				trigger_error(gTxt('form_not_found').': '.$name);
				return;
			}
			$f = $row['Form'];
			$forms[$name] = $f;
		} else {
		  $f = $row;
		  $forms[$name] = $row;
		}
	}
	trace_add('['.gTxt('form').': '.$name.']');
	return $f;
}
...
?>

Error pages

Just one more step left, 404/error pages (error_default in a standard Textpattern install). If you’d like a static error page too, there’s one more step you need to do.

In the file textpattern/lib/txplib_misc.php, on line 1827, you’ll find a function called txp_die (do a search for ‘function txp_die’ in your favourite text editor). Simply replace the code in that file with the code below.

<?php
...
function txp_die($msg, $status='503')
{
...
if (@$GLOBALS['connected']) {
  $out= @file_get_contents(txpath.'/../templates/pages/error_'.doSlash($code).'.php');
  if (empty($out))
    $out = safe_field('user_html','txp_page',"name='error_".doSlash($code)."'");
  if (empty($out))
    $out= @file_get_contents(txpath.'/../templates/pages/error_default.php');
  if (empty($out))
    $out = safe_field('user_html','txp_page',"name='error_default'");
}
...
?>

And you’re done! Congratulations, you now have a Textpattern install that can use template files!

10 Comments Comment feed

Thanks Steffan and TXP Tips for this new tip.

It’s worth mentioning the alternative of using cnk_versioning plugin, instead of hacking TXP core files.
Some may prefer one solution over the other.

Grmpf i wanted to Comment this article but i accidentally added my comment to this article instead :-S

Steffan – have you thought about extending this to CSS, as in serving static files, similar to rvm_ccs?

Interesting Jonathan — I hadn’t thought of that, no!

I always use static CSS files and link them in myself; I hadn’t thought about using the built in Textpattern one at all.

Will take a look at rvm_css, cheers!

This is great but will it work for txp 4.3?

A great tip! But a little too burdensome to this for all the sites i have.

BUt this php modification trick makes me ask the question: Can this not be added to the Core and set the linking to the external files via a Preferences setting?

@bici If I understand you correctly, you could indeed! Could even be a mini Plugin that just sets the directory (so you don’t have to do more Core hacking — not that I have anything against it)

@Zander There’s no reason why this wouldn’t work with Textpattern 4.3, however the line numbers won’t be exactly the same. I’ll will update the diff file and put it online shortly!

It would be fantastic if textpattern had this option out of the box – or at least a plugin.

I know there are various plugins that write out code to files. The drawback with those is that you need to disable it, create your page or form, enable it and then write your files again.

It’s so much faster creating and editing templates in a text editor.

  • xylpho
  • 14 July 2011

Hi,
I did these modifications on a fresh 4.4.1 install using Mamp, all seems to be OK (ie. no errors on admin side) but i can’t figure out how to call the external template. I miss something and i don’t know what.

Do i need to empty the templates in the admin side and make a call with <txp:php> or whatever else ?
Can you give me clues ?

Thanks in advance

  • xylpho
  • 14 July 2011

Forget my comment… I’m dumb
I placed the templates folder in the wrong level and did not change the path. After correction, all is working perfectly a on 4.4.1 install

Thanks for the tip !

Note : it’s often a critic on Textpattern, the way that all is stored in database, especially templates and forms. With this slightly modification i have a counter argument ;)

Add a comment

Use Textile help to style your comments