18 July 2010
Beginning
This is Part 3 of a three-part tutorial series, in which you use Dreamweaver CS5 to build a database-driven news page of a fictitious publication, Check Magazine. Parts 1 and 2 of this series showed how to build a simple content management system (CMS) for the news items. In this final part, working from a designer's image of what the finished page should look like, you'll add the necessary HTML, CSS, and PHP code to draw the contents from the database and display it. The contents of the page will change when a user clicks a link in the Archives or Recent Posts columns.
In the process, you'll learn how to format dates stored in MySQL, and add conditional logic to the PHP code to control which content is displayed. You'll also learn how to use the Recordset dialog box in Advanced mode. You don't need prior knowledge of PHP or SQL, but you should be prepared to dive into the code automatically generated by Dreamweaver's server behaviors and edit it.
The designer has given you a piece of artwork (or comp) showing what the news page for a fictitious publication, Check Magazine, should look like (see Figure 1).
It's your task to translate this concept into reality. In the first two parts of this tutorial series, you created the database table to store the news items and built a simple CMS to insert, update, and delete items. If you haven't completed parts 1 and 2, please do so now, because the site files and database are essential.
The comp shows the content displayed as three columns: Archives, Recent Posts, and the main column, which displays the two most recent posts. This means you need to create at least three recordsets:
Another challenge is to convert the dates stored in MySQL into different formats. The text links in the Archives column need to display the month and year, but the value passed through the link in a query string needs to be in a format suitable for filtering a recordset. Moreover, the dates in the main content area are formatted as "month date, year".
There's a lot of work ahead. It's time to fire up Dreamweaver.
Apart from the banner and menu at the top, news.php is a single image. Before doing anything else, you need to add the Point of View heading, and create the structure for the three columns of content.
<div> to hold the dynamic content immediately after the banner <div> by clicking the Insert Div Tag button in the Common category of the Insert panel/bar, or select Insert > Layout Objects > Div Tag.In the Insert Div Tag dialog box, use the settings shown in Figure 3, and click OK.
<div>, and click the Image button in the Common category of the Insert panel/bar, or select Insert > Image.In the Select Image Source dialog box, navigate to the images folder, and select blog_hdr.gif.In the Image Tag Accessibility Attributes dialog box, type Point of View in the "Alternate text" text box, and click OK. This inserts the blog heading image.
<div>, but after the image you have just inserted.To insert the first <div>, click the Insert Div Tag button in the Common category of the Insert panel/bar, or select Insert > Layout Objects Div > Tag again.
In the Insert Div Tag dialog box, use the settings shown in Figure 4, and click OK.
Selecting "Before end of tag" and <div id="blog"> inserts the new <div> immediately before the closing tag of the blog <div>.
<div> by clicking the Insert Div Tag button in the Common category of the Insert panel/bar, or selecting Insert > Layout Objects > Div Tag. Use the settings in Figure 5.
This time, the Insert pop-up menu is set to "After tag" and <div id="archive"> is selected in the pop-up menu alongside. This inserts the <div> after the one for the Archive column.
<div> using the following settings:
archive <div> with Archives, and format it as an <h3> heading.Press Enter/Return to create a new paragraph, and type Month & year. With your insertion point in the new paragraph, convert it to an unordered list by clicking the Unordered list button in the Property inspector in HTML mode.
recent <div> with Recent Posts, and format it as an <h3> heading.Press Enter/Return to create a new paragraph, and type Post title. Convert the new paragraph into an unordered list.
blog_posts <div> as an <h2> heading, and press Enter/Return to create a new paragraph.Type Updated on in the new paragraph.
The page should now look like Figure 7.
Next, you need to add style rules to the site's style sheet to turn the horizontal <div> elements into columns. The Archive and Recent Posts columns have colored backgrounds and need to be of equal height. Instead of applying backgrounds to the columns, you'll use an image as the background to the blog <div>, and float the two columns over it.
In the New CSS Rule dialog box, use the following settings:
Click OK to open the CSS Rule Definition dialog box.
Navigate to the images folder, and select blog_bg.gif.
Set Background-repeat to repeat-y.
Click OK. The background image tiles down the side of the blog <div> creating the illusion of two columns.
Click OK to open the CSS Rule Definition dialog box.
Deselect the "Same for all" check box for Margin, and set Left to 312 px.
Click OK.
The third column moves into place to the right of the colored backgrounds. It's too low down, but will move into place once the other columns have been floated.
In the CSS Rule Definition dialog box, set Color in the Type category to light gray (#CCC). Select the Box category, and set Width to 115 px. Click OK.
Set Color in the Type category to white (#FFF) and Width in the Box category to 135 px. Click OK.
Click the New CSS Rule icon. This time use the following settings:
•Selector Type: Compound
•Selector Name #archive, #recent
•Rule Definition: check_cs5.css
This compound selector will apply the same rules to both columns.
In the CSS Rule Definition dialog box, set Font-size in the Type category to 12 px.
In the Box category, set Float to left.
Deselect the "Same for all" check box for Padding, and set Top and Bottom to 10 px, and Right and Left to 15px.
When you click OK, the three columns should be correctly aligned (see Figure 8).
#archive h3, #recent h3 {
margin: 0 auto 10px 0;
text-transform:uppercase;
}
#archive ul, #recent ul {
list-style-type:none;
margin:0;
padding:0;
}
#recent li {
margin-bottom:0.7em;
}
#archive a, #recent a {
text-decoration:none;
}
#archive a:link, #archive a:visited {
color: #CCC;
}
#archive a:hover, #archive a:active, #archive a:focus {
color:#999;
text-decoration:underline;
}
#recent a:link, #recent a:visited {
color: #FFF;
}
#recent a:hover, #recent a:active, #recent a:focus {
color:#CCC;
text-decoration:underline;
}
#blog_posts h2, .updated {
margin: 0 5px 0 0;
background-color: #CCC;
padding: 10px 10px 0 10px;
}
.updated {
margin-bottom:10px;
padding-bottom: 5px;
font-size: 13px;
color: #646664;
}
.blog_entry {
padding: 0 30px 0 10px;
}
In Part 2 of this tutorial series, you learned how to use the Recordset dialog box in Simple mode. The recordsets needed for the news page are more complex, so you need to use Advanced mode. Working in Advanced mode requires an understanding of SQL, the language used to communicate with a database. Don't worry. I'll explain what you need to know as you go along.
The Archives links need to list the month and year in which items were added to the news table in the database. The updated column contains a MySQL timestamp, which contains the date and time. So, there's no problem finding the dates. The main task is to format them. Conveniently, MySQL's DATE_FORMAT() function is designed to do just that.
The Name text box and Connection pop-up menu are the same as in Simple mode, but the SQL area is where you build the database query. Dreamweaver gives you some help with the tree menus in the "Database items" area and the Add to SQL buttons, but you normally need to edit at least part of the query manually.
You'll see what the Variables area does later when building the recordsets to retrieve news items to display in the main column.
Note: Figure 9 shows a SQL query that selects all columns and records in the news table (an asterisk is shorthand for "all columns"). This happens because you can always switch from Simple mode to Advanced to edit a query. The next time you open the Recordset dialog box in Advanced mode, the SQL area will be empty. When you start using the tools in the "Database items" area, the asterisk will be replaced by the columns you select. Once you start editing in Advanced mode, you need to clear the SQL area to switch back to Simple mode.
Select updated, and click the SELECT button twice.
With updated still selected, click the ORDER BY button.
The query in the SQL area should now look like this:
SELECT news.updated, news.updated
FROM news
ORDER BY news.updated
This query selects the updated column twice, and uses the same column to determine the sort order. The date needs to be in two formats: the first to display the month and year, the second to use in a SQL query to retrieve the records for that period. However, this is as far as Dreamweaver will help you. The rest's up to you.
SELECT DATE_FORMAT(news.updated, '%M %Y') AS archive,
DATE_FORMAT(news.updated, '%Y-%m') AS link
FROM news
ORDER BY news.updated DESC
Note: There must be no space between DATE_FUNCTION and the opening parenthesis. Inserting a space triggers a MySQL error.
The MySQL DATE_FORMAT() function takes two arguments: the date column you want to format, and a string that specifies how to format it. You build the format string using plain text and specifiers, which begin with a percentage sign. The specifiers used here are:
%M: Month name in full (January, February)%Y: Year as four digits%m: Month number with leading zeroThere's a full list of MySQL DATE_FORMAT() specifiers in the Date and Time Functions section of the MySQL Reference Manual.
When you use a MySQL function in a SQL query, you assign the result to an alias, which is how the value will be listed in the recordset. So, this query formats the date as Month Year, and assigns it to the alias archive. It's also formatted as the year and month in numbers separated by a hyphen, and assigned to the alias link.
The other change is the addition of DESC, which returns the result in descending order—in other words, the most recent first.
DISTINCT after SELECT like this:SELECT DISTINCT DATE_FORMAT(news.updated, '%M %Y') AS archive,
DATE_FORMAT(news.updated, '%Y-%m') AS link
FROM news
ORDER BY news.updated DESC
Recordset (getArchives).archive in the Bindings panel, and click the Insert button at the bottom of the panel. This inserts a dynamic text object in the unordered list.Note: Be careful to click the correct lightning bolt icon. Both the Name and Value fields have one. It's the one on the Value field that you want.
link from the recordset in the Dynamic Data dialog box.<li> in the Tag selector at the bottom of the Document window to select the list item that contains the dynamic text object and link you have just created.<div> looks like Figure 11.
Creating the links to the recent posts follows the same pattern as for the archives. There are no dates in the recordset, so creating the SQL query is a lot easier. Rather than retrieving all records, you need only the 10 most recent records. Because the results of the recordset will be displayed in a repeat region, your first instinct might be to use the option in the Repeat Region server behavior to show 10 records at a time. However, this generates a lot of unnecessary code if you don't need to use the Recordset Navigation Bar. It's more efficient to set the limit in the SQL query.
You need the primary key and title of the 10 most recent records, so select post_id, and click the SELECT button. Then select title, and click SELECT.
The records should be ordered chronologically, so select updated, and click ORDER BY.
The query Dreamweaver has built in the SQL area should look like this:
SELECT news.post_id, news.title
FROM news
ORDER BY news.updated
DESC at the end of the ORDER BY line.LIMIT followed by the required number at the end of the query. After editing, the SQL area should look like this:
SELECT news.post_id, news.title
FROM news
ORDER BY news.updated DESC
LIMIT 10
post_id (see Figure 12).
getRecent recordset to the unordered list in the Recent Posts column. This is the same procedure as you used for the Archives column.Select the "Post title" text in the Recent Posts column, and delete it.
In the Bindings panel, select title, and click the Insert button at the bottom of the panel.
With the dynamic text object still selected, click the Browse for File icon alongside the Link text box in the Property inspector, and select news.php. Then click the Parameters button.
In the Parameters dialog box, type post_id in the Name field. Then select the Value field and click the lightning bolt icon to open the Dynamic Data dialog box. Select post_id from Recordset (getRecent). Close all open dialog boxes.
<li> in the Tag selector at the bottom of the Document window to select the whole list item in the Recent Posts column, and apply a Repeat Region.There's now more than one recordset on the page, so you need to select the correct one in the Repeat Region dialog box.
Select getRecent from the Recordset pop-up menu, and choose the option to show all records.
Click OK to apply the Repeat Region server behavior.
recent <div> looks like Figure 13.
All that remains is to display the blog posts in the main column. When the page first loads, you want to display the two most recent posts, but when a link is clicked in the Archives column, the page should display the posts from the selected period, and when a link is clicked in the Recent Posts column, it should display the selected post. The question is how to control the display.
Each scenario requires a different recordset, but you want to display only one of them. One approach is to create three recordsets, each with its own repeat region, and then add some conditional logic to display the one you want. However, that's overkill. There's no point in querying the database if you're not going to use the result. The solution you're going to use is to build three recordsets, and then merge them into one. It involves some hand-coding, but if you follow the instructions carefully, you should have no problems.
The first stage is to create a recordset and repeat region to display the two most recent items when the page first loads.
You want to display all columns, except post_id. In turn, select each of the remaining columns—title, blog_entry, and updated—and click the SELECT button.
With updated still selected, click ORDER BY.
This produces the following query in the SQL area:
SELECT news.title, news.blog_entry, news.updated
FROM news
ORDER BY news.updated
DATE_FORMAT() format string for this is '%M %e, %Y'. This introduces a specifier you haven't used before: %e, which displays the day of the month without a leading zero.You also want the results in reverse order, so you need to add DESC to the ORDER BY clause of the SQL query.
To limit the number of results to 2, add LIMIT 2 at the end of the query.
The amended SQL looks like this:
SELECT news.title, news.blog_entry,
DATE_FORMAT(news.updated, '%M %e, %Y') AS formatted
FROM news
ORDER BY news.updated DESC
LIMIT 2
Click OK to close the Test SQL Statement panel, and then click OK to close the Recordset dialog box.
Recordset (getDisplay). Replace the placeholder text in the main column with dynamic text objects for the title and blog_entry columns, and position the formatted dynamic text object alongside the words "Updated on" (see Figure 15).
blog_entry dynamic text object, and drag upwards and left to select the three dynamic text objects in the main column.In the Repeat Region dialog box, select the getDisplay recordset and the option to show all records.
Don't worry if the layout in Design view shifts. If you selected the elements correctly, the page should display correctly when you test it.
There are just two problems: the date should be part of each item's heading, and the blog posts are solid blocks of text. The new lines in the underlying code are being ignored.
Dynamic Text (getDisplay.blog_entry) to open the Dynamic Text dialog box. From the Format pop-up menu, select Convert – New Lines to BRs (see igure 17).
This wraps the dynamic text object in the PHP nl2br() function, which converts newline characters to HTML <br /> tags.
Click OK to close the Dynamic Text dialog box.
The next stage is to create separate recordsets for the archives and recent posts. The links in both columns use a query string to pass a variable through the URL. You use these variables to filter the recordsets in the same way as you did in Part 2 to update or delete a record. However, you can't use the Recordset dialog box in Simple mode, because the dates need to be formatted. Instead, you define a placeholder variable for the SQL query.
After you have created the recordsets, you need to merge the code manually and build the conditional logic to control the display in the main column. To make this easy, name the recordsets getDisplay2 and getDisplay3.
Recordset (getDisplay) in the Server Behaviors panel to open the Recordset dialog box.Enter getDisplay2 in the Name text box, and paste the query from your clipboard into the SQL area.
You don't need to limit the number of records, so delete LIMIT 2. The query should now look like this:
SELECT news.title, news.blog_entry,
DATE_FORMAT(news.updated, '%M %e, %Y') AS formatted
FROM news
ORDER BY news.updated DESC
updated column in the news table. Click the WHERE button. This adds a WHERE clause to the query like this:SELECT news.title, news.blog_entry,
DATE_FORMAT(news.updated, '%M %e, %Y') AS formatted
FROM news
WHERE news.updated
ORDER BY news.updated DESC
On its own, this is meaningless. Dreamweaver expects you to complete the WHERE clause manually. To select the correct records, the WHERE clause needs to match the value in the updated column to the value passed through the query string from one of the links in the Archive column.
The value in the query string is formatted as a year and the number of the month (with a leading zero, if necessary) separated by a hyphen. To compare this with the updated column, you need to format the column in the same way. For example, if the value in the query string is 2010-06, the query needs to find all records where DATE_FORMAT(news.updated, '%Y-%m') matches 2010-06.
WHERE clause like this:WHERE DATE_FORMAT(news.updated, '%Y-%m') = var1
This formats the updated column and compares it to var1, which is a placeholder for the value passed through the query string. You can use any name for the placeholder, as long as it doesn't clash with anything else in the SQL query.
Click the plus button alongside Variables to open the Add Variable dialog box, and use the following settings (Figure 19):

You need to use Text as the Type because the value contains a hyphen. You could also choose Date, but there's no difference in the way the PHP code handles Text or Date.
Setting the default value to -1 prevents the recordset from returning a result if the variable in the query string is missing.
PHP stores variables passed through a query string in what's called the $_GET array. To access the value, put the name of the variable in quotes between square brackets after $_GET. PHP is case-sensitive, so GET must be in uppercase.
Click OK to close the Add Variable dialog box.
WHERE and ORDER BY lines, leaving the following:SELECT news.title, news.blog_entry,
DATE_FORMAT(news.updated, '%M %e, %Y') AS formatted
FROM news
post_id in the news table. Click the WHERE button. Add = var2 at the end of that line so the query looks like this:SELECT news.title, news.blog_entry,
DATE_FORMAT(news.updated, '%M %e, %Y') AS formatted
FROM news
WHERE news.post_id = var2
The query string in the Recent Posts links contains post_id, which is the record's primary key. It's a whole number, so you need to set the Type to Integer.
Now comes the part that strikes fear into the hearts of many designers—diving into Code view. It's not as scary as you might think. Even if you don't want to write your own code, it's important to understand what the code Dreamweaver has generated does.
DOCTYPE declaration. This is the code that queries the database and creates the recordsets ready for display in the page. There's a long function definition around lines 3–32, which creates a function called GetSQLQueryString(). Its role is to protect your database from malicious attacks called SQL injection.The rest of the code is for the five recordsets you have created. You can recognize them easily because the PHP variables are built from the recordset names. So the SQL query for the getArchives recordset is assigned to a variable called $query_getArchives, the getRecent query is in $query_getRecent, and so on.
getDisplay recordset (see Figure 20).
Note: Use the line numbers in the screenshots and instructions only as a guide. The line numbers in your page might be different.
getDisplay3 recordset code, insert a couple of blank lines, and paste the getDisplay code in the space you have just created. The code should look like Figure 21.

if to elseif. The edited code should look like Figure 23.
Change the name of the variable shown at the beginning of line 56 to $query_getDisplay (removing the 3).
What you have done is to create a conditional statement that creates a different SQL query ($query_getDisplay) depending on the following criteria:
archive, use the SQL query for the Archives column.post_id, use the SQL query for the Recent Records column.getDisplay query.Note that the PHP code uses the same logic:
if (condition 1) {
// do this
} elseif (condition 2) {
// do something else
} else {
// default action
}
The conditions are controlled by if, elseif, and else. Once you get used to it, PHP is not difficult to follow.

This releases from memory the results from the recordsets after they have been used. The getDisplay2 and getDisplay3 recordsets no longer exist, so you need to delete the code shown on lines 122 and 124.
min-height: 650px to the #blog style rule to prevent the Recent Posts column being truncated when a single blog item is shown.The ability to display different content in the same page in response to user's actions is just one aspect of creating dynamic websites with a server-side technology, such as PHP. Dreamweaver's server behaviors can help give you a head start, but as you have seen in this final part of the tutorial series, moving beyond basic functionality requires knowledge and effort on the part of the developer. You also need a good understanding of database design and SQL. Hopefully, this series has whetted your appetite to learn more about this vast, yet fascinating subject.
Both PHP and MySQL have excellent online documentation:
Dreamweaver CS5 also has full documentation for all core PHP functions and classes, together with examples of how to use the code. The documentation appears automatically when you invoke code hints by pressing Ctrl+spacebar in a PHP code block.
Reading a reference manual is fine when you know what you're looking for, but the following online resources teach PHP in a more structured way:
You might also want to explore my books that deal specifically with PHP development in Dreamweaver:

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License
Tutorials and samples |
| 04/23/2012 | Resolution/Compatibility/liquid layout |
|---|---|
| 04/20/2012 | using local/testing server with cs5 inserting images look fine in the split screen but do not show |
| 04/18/2012 | Ap Div help |
| 04/23/2012 | Updating |