Custom Content Management with PHP
by Thomas Perl, in Tutorials - Sat, Sep 11th 2004 00:00 UTC
It is well known that you can create powerful Web pages with PHP. Often,
the question arises: How are these pages made? This tutorial wants to
give you some hints on how to make your Web site appear more managed
from both inside and outside. These are my own approaches to Web
development; I hope you find them useful. Take these things as ideas
rather than good practice.
Copyright notice: All reader-contributed material on freshmeat.net
is the property and responsibility of its author; for reprint rights, please contact the author
directly.
About the hints
Each hint in this tutorial can be implemented by itself without the
others, but sometimes, it's more useful if you combine them. It depends
on you to decide which hint is good for your site.
Clean directory structure
Are you tired of calling a subpage of your site
http://www.example.com/index.php?page=news&id=45? You
could have a stylish URI in the form of
http://www.example.com/news/45/. This gives better-sounding
addresses, and your visitors may more easily remember your URIs. All you
need is the Apache Web server or a browser in which this
.htaccess file will be processed in the same way:
RewriteEngine on
RewriteBase /news/
RewriteRule ^.*$ handler.php
These three lines instruct Apache to rewrite all
URIs from the base directory /news/ matching
the rule ^.*$ to the handler.php
script.
Place this file in your newly-created /news/ directory,
then create a handler.php file, which will handle all the
requests beneath the /news/ tree. In other words, all URLs
you request within that directory will be handled by
handler.php. To get an array of "parameters" that
are passed to handler.php, you can use this function:
function get_url_params( $base_url)
{
$request = substr( $_SERVER['REQUEST_URI'], strlen( $base_url));
if( substr( $request, -1) == '/')
$request = substr( $request, 0, -1);
return explode( '/', $request);
}
Use it in handler.php like the following:
get_url_params( '/news/');
You will receive an array with the parameters, which you can process as
you wish. You could improve the get_url_params() function
by adding code for processing a ? (and everything behind
it) in the request URI.
I use this technique to get some fancy URI mapping of my Web site. It's
not any harder than using a single index.php which handles
all requests, and the benefits are clearly visible. You will be able to
make URLs on your Web page that don't have to change, which is exactly
what Cool URIs don't
change tells you is good practice. (This document got me into
making this URI mapping system for my Web site; it's really worth
reading.)
Creating a template framework
You can use templates for outputting both static and dynamic content.
You will want to create a directory in which you put the templates. You
should secure this directory using this .htaccess file:
allow from none
deny from all
This will instruct Apache to deny all access to the template
files directly. Access using template functions is still granted,
because they're not directly accessed.
You will now want to write a template function. Here's what I currently
use for my site:
function template_create( $template_name, $mapping = NULL)
{
$template_data = file_get_contents( $_SERVER['DOCUMENT_ROOT'] .
'/templates/' . $template_name . '.template');
if( NULL != $mapping)
return str_replace( $mapping['from'], $mapping['to'], $template_data);
else
return $template_data;
}
This means I have my templates in the /templates/ directory
of my document root and that the files have the extension
*.template (which isn't necessary; you could name the
extension of your templates as you like). If you include the
$mapping parameter, this should be an array with two
elements: $mapping['from'] and $mapping['to'].
All occurrences of the "from" element will be replaced with the "to"
element. Both elements can also be arrays, which results in all elements
in the "from" array being replaced with the corresponding elements in
the "to" array. Here is an example of how you could use this:
$time = time();
$text = 'This is a Test';
$mymap = array(
'from' => array( '%%TIME%%', '%%TEXT%%'),
'to' => array( $time, $text)
);
template_create( 'my_document', $mymap);
Where the file /templates/my_document.template could look
like this:
<p>Hello. The time is %%TIME%% and here is some text:</p>
<p>%%TEXT%%</p>
You should now have seen how easy it is to create templates for pages
and how to fill them with dynamic content. This is especially useful if
you want to create templates for displaying dynamic data from databases
and such. You can surely improve this by creating a function which reads
one row from a database table and fills a mapping variable with data
from that row, returning a valid mapping for the
template_create() function.
Using templates for a unique layout
This is a short and easy one. Let's say you want to create a unique
layout for a page, but you don't want to include the full code in every
file or script you write. Use the templates hint above to create
template functionality and include it in every subpage. Then, use it
like the following (assuming header.template and
footer.template include all the code for the beginning and
the ending of the page):
template_create( 'header');
// place content output here
template_create( 'footer');
Yes, that's all!
Make database access abstract
Here's some more code for your include directory. After some time, it's
easier to make queries in this fashion than to make a
mysql_query everywhere you need some data from the
database. It also gives more sense to the code and makes it more
readable because you just see the function call with the important
parameters.
function database_get_single_element( $table_name, $key, $value);
function database_select_multiple_elements( $table_name, $from, $to,
$order = NULL, $how = 'ASC', $key = NULL, $value = NULL);
function database_get_random_element( $table_name, $key = NULL, $value = NULL);
function database_get_column_sum( $table_name, $column, $key = NULL, $value = NULL);
function database_get_next_element( $query);
function database_count_elements( $table_name, $key = NULL, $value = NULL);
The database_get_single_element() function will select and
mysql_fetch_assoc one row of the table named by
$table_name. There will also be a WHERE part,
and the $key field in the table must have the
$value value.
The database_select_multiple_elements() will return a
mysql_query of the same things. $from and
$to are for the LIMIT part of the query. The
data can then be fetched with database_get_next_element(),
which is exactly the same as mysql_fetch_assoc, but has a
more informative name.
database_get_random_element() will use the ORDER BY
RAND() LIMIT 1 SQL query words to select some random element from
the table.
Finally, database_count_elements() counts the number of
rows of the results. This is good for counting how many elements
another query will return.
These are just some hints of what I mean by database abstraction. I'm
sure that you'll probably need other functions which better suit your
needs, and you might not need all the functions I've shown. Let me tell
you from experience that it will get a lot easier when you start using
these functions instead of simple queries. And if you have some very
complicated queries, make a function for each of them. If your database
layout changes or if you use another database instead of MySQL (which is
certainly possible in PHP), you do not have to change all queries, but
simply fire up your editor on the database include files and change all
queries there.
Author's bio:
Thomas Perl, an Austrian student at
HTBL Pinkafeld, became
involved with Linux and Open Source in the middle of 2003. Having
re-designed (and re-programmed) his Web site every few weeks since 2002,
he has gained experience in Web development with open standards, with
PHP and MySQL being the most important ones. He's also spent some of
his free time working on Open Source projects like FunkyMD and HighLnk.
T-Shirts and Fame!
We're eager to find people interested in writing articles on
software-related topics. We're flexible on length, style, and
topic, so long as you know what you're talking about and back up
your opinions with facts. Anyone who writes an article gets a
t-shirt from ThinkGeek
in addition to 15 minutes of fame. If you think you'd like to try
your hand at it, let jeff.covey@freshmeat.net
know what you'd like to write about.
[Comments are disabled]
|
Referenced projects
Apache - A high performance Unix-based HTTP server.
MySQL - A fast SQL database server.
PHP - A high-level scripting language.
|
Comments
[»]
Templating template languages
by antrik - Nov 12th 2004 16:59:49
I'm regualarily amazed how much fuss is made about templating sytems for
PHP...
Can someone please explain to me what this crap is good for? After all,
PHP
*itself* is a templating language! What's the point then of using
templates
with some weird custom syntax in PHP? What does the fancy function
presented
above, or any of the more formalized PHP templating systems offer, that I
can't
do just as well using "require('template.inc.php')" with
"<?=$time?>" instead
of some crazy "%%TIME%%"?
[reply]
[top]
[»]
Another usefull database function
by Mikhail Vladimirov - Oct 13th 2004 01:32:31
I found, that a sprintf-like query formatting function can also be very
usefull. It should accept additional format specifier (e.g. %e) for string
fields, which should be escaped.
[reply]
[top]
[»]
Thanks!
by Nermal - Sep 11th 2004 15:49:28
These are just the kind of tips I need to help me with my website code
cleanup. Many thanks for the taking the time to write this. The only
downside is that it only highlights how dodgy some of the current code is
;)
[reply]
[top]
[»]
And where's the CMS?
by Soenke J. Peters - Sep 11th 2004 09:16:30
Thanks for your basic introduction into the world of PHP driven websites.
But a software that's worth beeing called a CMS is far more than just
generating pages from templates and filling them with some "dynamic"
content.
[reply]
[top]
[»]
Re: And where's the CMS?
by Michael Shigorin - Sep 11th 2004 14:19:04
> But a software that's worth beeing
> called a CMS is far more than just
> generating pages from templates and
> filling them with some "dynamic"
> content.
Well the author didn't mention "S". :-)
To fill in the gaping hole, I'd suggest curious reader looking for
powerful CMS to evaluate TYPO3, Drupal, eZ
publish; maybe Xaraya (not mentioning
Perl, Python and Java-based engines since the topic seems to be PHP, for
good or whatever).
As for myself, I'm quite happy with TYPO3 but it's really a high-end
CMS/CMF with fair warning of at least a month of advance reading required
attached (still my testsite was alive in a few hours, the docs are very
nice right from README; and my template started working the same week,
Getting Started and MTB are just as good).
So if you're just looking at some *Nuke, then it may be just worth using
-- if it's not PHPNuke (NukeCops flavour or PostNuke branch may do, but
dumping code worse than Sendmail as a freebie while selling kind of secured
version isn't a good business model at all).
But please please please, do your googling better next time you reinvent a
CMS -- that is, decide you need to write one from scratch! Just look at
TYPO3 screenshots and think of those man-years that are needed for
something to be called "S" these days, and "S****m" rather than "S**t".
-- Michael Shigorin
mike SOMEWHERE AT altlinux PLUS DOT org
[reply]
[top]
[»]
Re: And where's the CMS?
by PerlChild - Sep 11th 2004 20:55:28
Mambo might also be worthy of consideration, and http://www.cmsmatrix.org/ is a good
place to see what features are available
[reply]
[top]
[»]
Re: And where's the CMS?
by Michael Shigorin - Sep 12th 2004 00:37:47
> Mambo might also be worthy of
> consideration, and
> http://www.cmsmatrix.org/ is a good
> place to see what features are available
Re link, I'd really better point to some of these (looked at a pack of
those incl. opensourcecms.com while hunting myself). Thanks.
Re Mambo, a friend of mine uses it for several sites and we have compared
thins. Yes it's lightweight and may be easy to install but *total* lack of
page structure (this is a design fault I believe) and consequent navigation
construction by hand just killed it off for me at once. (you see, I
understood that structure *is* critical in my wee university days --
applied to websites)
Another friend who finally went to Plone from Mambo told it was no good
inside, and I tend to listen to him. Still to my regret (after several
dozens KB of frustration) Plone+reStructured text is only acceptable to
fanatics of Python with its braindamaged obtrusion of indentation which is
completely incompatible with most current browsers' editors (you can use
normal editor from elinks by Ctrl-T, emacs people must have something
appropriate too, but coping with Mosex is no good and the author told us
it's a hack).
So after a few days of quite intensive "looking at" freshmeat CMS category
with "Mature/Stable" filter applied and rehashing friends' resumes on
things I knew they used, finally settled with TYPO3 and you know what? It
does have the community to fall in love with. :-)
As established and friendly communities are really more important than
this-minute product state in my experience, this just couldn't be ignored.
Well, and product itself is awesome (although not perfect) and really just
another kind of sport compared to Mambo and friends. :-)
Don't get me wrong, I appreciate the versatility of products available --
it's just that even *me* who is humble project manager at our free software
consulting firm here in Ukraine and a bit of
developer/maintainer/contributor in ALT Linux Team -- even me found that
time-hungry TYPO3 worth investing time into to save my (and not only my)
time in the future. So far, it pays. :-)
-- Michael Shigorin
mike SOMEWHERE AT altlinux PLUS DOT org
[reply]
[top]
[»]
Re: And where's the CMS?
by Thomas Perl - Sep 12th 2004 13:27:33
> Thanks for your basic introduction into
> the world of PHP driven websites.
>
> But a software that's worth beeing
> called a CMS is far more than just
> generating pages from templates and
> filling them with some "dynamic"
> content.
The title tells it: Custom Content Management in PHP. I didn't mean
it to be though as a CMS, as the other commentors said: if you would want a
CMS, you wouldn't go code it yourself most of the time - there are
fully-featured packages already out there.
What I wanted to show is how to do some rather small (and unique) site in
PHP/MySQL, without all this "generic" stuff a CMS brings to you.
Ever seen a PHPNuke-powered Site with many "modules" and features, but no
real content? Not every site needs a CMS. Of course, if you want to do a
big site with CMS, you wouldn't want to go with this article, hehe. Thanks
for the comment.
Enjoy.
[reply]
[top]
[»]
Re: And where's the CMS?
by Melvin - Sep 20th 2004 05:51:25
Then you should have call it Custom Templating System ;)
Anyways, I like it... I thing is the best way to do templates even
I have use a lot of smarty and others alike for some jobs that required
its use.. But I've been using something like these for years and I haven't
found anything better so far.
What I usually try not to do, is the replacement of strings in the
templates, I rather do all the work with functions or classes right into
the file..
Since I have to use other languages for web apps I like to keep some
standards in the way I program.
I like this approach, but I think is just not the right title
Regards!
[reply]
[top]
[»]
Re: And where's the CMS?
by Thomas Perl - Sep 27th 2004 12:03:21
> Then you should have call it Custom
> Templating System ;)
On second thought, yeah that would have been the right title for
it, I guess :) Anyway, I'm glad you like it (the content, not the title,
hehe).
[reply]
[top]
[»]
Re: And where's the CMS?
by Per Fisker - Dec 15th 2004 04:29:44
> Then you should have call it Custom
> Templating System ;)
>
> Anyways, I like it... I thing is the
> best way to do templates even I have use
> a lot of smarty and others alike for
> some jobs that required its use.. But
> I've been using something like these for
> years and I haven't found anything
> better so far.
>
> What I usually try not to do, is the
> replacement of strings in the templates,
> I rather do all the work with functions
> or classes right into the file..
>
> Since I have to use other languages for
> web apps I like to keep some standards
> in the way I program.
>
> I like this approach, but I think is
> just not the right title
>
> Regards!
You do have a point, but actually its my experience that ppl in common
tend to utilize only the template part of the CMS solutions in todays
projects.
The parts missing before being a competitive CMS is in general: The
posibility to introduce role handling like writers and publishers and
introducing timed content handling.
[reply]
[top]
|