PHP for Domino Developers, Part 6, Subforms
This article is the final part of a series of articles that aim to introduce the LAMP platform to Domino Developers. So far we've covered just about all of the principles required to create a PHP web application. These include SQL database and table creation, FTP clients and servers, HTTP request methods and the PHP code needed to create table entries.
In this last part of the series we will cover one more feature of Domino that we need to replicate in PHP. Subforms. There are other features of Domino, such as searching and ACLs that we still need to cover but they are less essential and will be discussed in future advanced PHP articles.
Where Subforms fit in with the PHP model:
A long time ago, I stopped using Notes to create client applications and concentrated solely on web applications. The more web applications I created with Domino the more I found myself relying on my own HTML. In the end I found myself using nothing but Pass-Thru HTML to create and layout pages and the items within them. My confidence in Domino doing it right had slowly diminished.
In a previous article on this site called Designing Modular Domino Applications I described how I use Subforms to split the HTML of a page in to logical sections, or modules. As a simple example, think of a page that is made up of 3 distinct sections - Banner, Navigator and Content. Banner and Navigator are usually the same across all pages and Content is the only part that tends to change. If you have two or more pages with the same design and you change something in Navigator, you need to make the change more than once. We want to avoid this. To do so, we split the parts of the page that are always the same in to Subforms. These Subforms are then added in the correct place to create a template for all pages. Should the Banner need to change, you do it once in the Subform and not on all the Forms.
The same principle applies to all web pages, not just Domino. There's always parts of a page where the content is fixed and where we want to avoid coding the same thing over and over. This article shows how to achieve the same thing with PHP. It concludes with the download of all the code needed for the full version of the website we've been working toward.
Creating The Template in PHP:
Before we talk about how to split pages in PHP, let's look at an example HTML page to get a better picture of what we mean:
<html>
<head>
<title>Simple HTML Page</title>
</head>
<body>
<div id="banner">
Welcome to our simple HTML page
</div>
<div id="navigator">
<a href="http://www.codestore.net">Leave?</a>
</div>
<div id="content">
Hope you enjoy your stay.
</div>
</body>
</html>
Here, we have the three sections we talked about. Also, there's the page's head section which stays all but static throughout. We can start to split this page up and only include the part of a page that will change. Here's how:
<?php include "head.php" ?>
<?php include "start.php" ?>
<div id="content">
Hope you enjoy your stay.
</div>
<?php include "end.php" ?>
We use the PHP include() statement to include the parts of the page in the right placess to build the whole page. As with the Subform approach, if one of these parts change, you only need to edit one file. The contents of these files should be obvious but I will describe them anyway. First head.php which simply contains:
<html>
<head>
<title>Simple HTML Page</title>
</head>
Notice there's no PHP code in there? So why didn't I just call it head.html, instead of head.php? We shall see why later, when we need to make the contents of the included files dynamic.
The contents of start.php are:
<body>
<div id="banner">
Welcome to our simple HTML page
</div>
<div id="navigator">
<a href="http://www.codestore.net">Leave?</a>
</div>
And, finally, the content of end.php is simply:
</body>
</html>
This is a very simple example of how to split a page up logically. Every page is different and the way that you go about making the splits will change for each design. It's also down to you how many of these splits you make. You might not like to have both the banner and navigator <div>s in the same file and instead decide to split it in to two files, called banner.php and navigator.php. It's up to you. The only thing I will say is that you really should use this technique of splitting pages in to sections. If you don't you will find managing the design of your site soon turns in to a real nightmare.
A Problem With This Approach:
You can see in the above sections that the file called head.php contains the <title> tag. This is very likely to change on every page in which head.php is used. How do we go about changing the title of a page then? Well, we could split head.php in to two parts and wrap them round the <title> tag but this is an unnecessary step. Instead, we can define the page's title as a variable and reference it in the included file. The new page would look something like:
<?php $title="Simple HTML Page"; include "head.php" ?>
<?php include "start.php" ?>
<div id="content">
Hope you enjoy your stay.
</div>
<?php include "end.php" ?>
And head.php would look like this. Hence the reason we ended the file's name in .php and not .html!
<html>
<head>
<title><? echo $title; ?></title>
</head>
The thing to note is that we can reference variables that were defined in the main part of the page from within the files that we include.
About Computed Subforms:
Taking the Subform approach to another level I often use Computed Subforms to include HTML based on a certain condition. Let's say we want to use a different Subform for read mode and edit mode. A Computed Subform with this formula would do it:
@If(@IsDocBeingEdited; "sub_entry_edit"; "sub_entry_read")
We can do the same thing really easily in PHP. Assuming edit mode is indicated by the presence of a URL parameter called "edit", the code would be:
if ( isset($_GET[ "edit" ]) ) {
include "entry_edit.php";
} else {
include "entry_read.php";
}
Not limited to HTML includes:
As we saw early on in this series of articles, we used the include() statement to import the database connection settings in our db.inc file. Obviously we can include files that contain nothing but PHP code. With this in mind it's worth mentioning that using include() is a nice way to add code libraries to your pages. Add all your common functions to a separate PHP file and include it at the top of all your pages to have them available always.
Advanced Templates:
As templates go, this is fairly primitive. Things get a little more complicated when you start thinking about separating application logic and content from its presentation. This is when "template engines" like Smarty come in. It lets designers and developers work on the same pages without getting in each others way. This is a real templating system. What I've talked about isn't really. It's just a way of making maintenance a little easier. If you want to get really smart, consider using Smarty.
The Finished Product:
Now that we've got Subforms out of the way I can let you download the "finished" product safe in the knowledge you know what all the code does. I've added the site as a zip to this document. It's not like Domino where all the code and files are nicely contained in one .nsf file. Most PHP sites you come across will be made up of lots of different files. of different types, contained in different folders.
PHP-Journal-v1.0.zip
Download the Zip and extract it to a folder on your PC. Make sure that you choose to keep the folder structure when you do the extraction.
With the folder structure still intact, upload the "journal" folder to your LAMP server. If you've been following all the other articles this should be all you need to do. You now have an exact copy of this site. Which is of course a copy of this site, created with the Notes Personal Journal template. The bits missing will be added in future LAMP articles.
Summary:
This series of articles has taken a hell of a lot longer to write than I first imagined. Sometimes you forget just how much knowledge is required in our line of work. If you didn't know any of this to start out with, you should, at least, appreciate the job you have as a Domino Developer. When I started I never said it was going to be easy. It's not. But, while it's not easy to develop with, it IS rewarding. Now that you know all of this you can easily take PHP out of the equation and replace it with the language of your choice. Be it ASP or JSP or whatever. You now have the base knowledge to move out of Domino in to the real world of web development.
Something I've tried to avoid is launching in to a slanging match. It would be very, very easy to list a whole host of reasons PHP is our new best friend. I try my best not to. Instead, you can make up your own minds. Hopefully by now you've started to see how web-friendly PHP is. This is because it's always been about the web. It's open source and has been tailored to the web, by web developers. The same can't be said of Lotus Domino. The product has tried to cater for the web and, to some extent, it's done it well. But it has so many little shortcomings that, when you add them all up, they become an infuriating mess of hacks and tricks required to get anything to work. As a simple example there's the infamous "No documents found" message we will all be familiar with. On this site I've written about a way to change the way it looks. The ensuing list of responses go on to discuss ways of hacking the HTML produced to hide this message, at the client. The way you deal with empty tables in PHP is completely down to you. For me, what I want out of the platform I use, be it PHP or not, is the complete control of the HTML that gets sent to the user. Not just because I worry about people viewing the source and picking it apart from a developer's point of view but because I want complete control of what the user actually sees.
Anyway, I don't really want to get started on that. What I did want to do is get you all to the point where you have no excuse not to see for yourself. This set of articles should be an exhaustive introduction to all the skills you need to know. If you want to ask anything else or add something that you think is missing come over to the PHP Bulletin Board I've set up for Domino Developers to talk about LAMP. Anything goes!
Hope you've enjoyed reading along. I've actually enjoyed writing them. What I really hope you enjoy is having the ability to go out and create your own PHP site. Just think of what you can make it do...
is_int()
Looking at your code in entries.php
'if ( isset($_GET['id']) && is_int((int)$_GET['id']) && isset($_GET['edit']) )'
Your trying to make sure that 'id' has been submitted and is a integer.
Whoever 'is_int((int)$_GET['id'])' doesn't do what you want. You need to use 'is_numeric($_GET['id'])'. Do a test and you will see that 'is_int((int)$_GET['id'])' always return 1 (true).
Reply
Re: is_int()
Thanks Bottsie. I've since learnt this too but neglected to come back and repair my mistakes ;o) No need now as you've done my job for me...
Jake
Reply
PHP Demo site - with DHTML Editor
Thank you Jake for posting these articles. I have been experimenting with PHP for the last little while. One thing I added to the your sample Journal database was the DHTML Editor from the sandbox (http://www-10.lotus.com/ldd/sandbox.nsf/ecc552f1ab6e46e4852568a90055c4cd/0ecbfc 80064383e600256bd8003a835e?OpenDocument).
There some bugs with it but it shows how you can copy and paste entire MS Word documents in the <textarea> and still have the same formatting.
http://www.dominokits.com/samplesjournal
I am also looking how I can incoropate Next Page and Prev Page links.
Note: I will be working on that journal http://www.dominokits.com/samplesjournal (as time permits) and will be adding other things such as a search, column sorting, attachments, and images.
If things go well, I will also incorparate the active X that QP provides for uploading and downloading attachments (drag and drop).
Thank you Jake for getting me initiated on LAMP. It is quite refreshing not having to worry about Domino servers!
regards,
Jose Zaldivar Calgary, Canada
Reply
Re: PHP Demo site - with DHTML Editor
Nice one Jose. It's good to see that people *really* do do something with what I write about ;o) Makes it all worthwhile.
Jake
Reply