From HTML mockup to a full Drupal site: a tutorial - Part II: Site Setup, Content and Modules

January 31, 2008

Continuing on from Part I: Introduction and Installation.

So we've got the makings of a site now. Let's build the site out to the client's content mockup and requirements spec. We'll build the navigation, add all of the content, build the content type for news and setup the appropriate views. After we're done with all of that, we'll focus on integrating our BeeEss theme with our new Drupal site in Part III of this series.

General site information

We need to put some basic information about our site into our new Drupal system. Navigate to '/drupal/admin/settings/site-information'. You can also find it on the 'Administer' page under the 'Site configuration' section. Enter the title, administrator's e-mail, slogan, mission and footer. We'll use all of these in our theming, so be sure to enter values for each of them. For example, the 'Slogan' will be used in the page title like this:

<title>(current-page) | (site-title) - (slogan)</title>

This, of course, is a function of theming and may not be the same with all Drupal themes, but it'll help you decide what your slogan should be for our example site.

Here's what I'm putting in each of the fields:

Title: BeeEss
E-mail address: [email protected]
Slogan: Syracuse, Albany, Rochester and Central NY specialists in natural stone restoration and terrazzo restoration.
Mission: <p>We strive to promote an aesthetically pleasing and healthy environment in commercial and public buildings by restoring and preserving their natural stone.  <a href="value-proposition" title="Learn more about how BeeEss can help with your Syracuse, NY natural stone restoration or terrazzo restoration project.">Learn more</a>.</p>
Footer message: <div id="footer-address">BeeEss, Ltd.  7 Adler Dr., East Syracuse, NY 13057</div><div id="footer-copyright">Copyright 2007 BeeEss Ltd.  All Rights Reserved.<br />Developed by <a href="http://graffetto.com" title="Graffetto Technologies">Graffetto Technologies</a>.<br /><a href="http://validator.w3.org/check/referer" title="XHTML 1.0 Strict Compliant">XHTML</a> | <a href="http://jigsaw.w3.org/css-validator/check/referer" title="CSS Compliant">CSS</a> | <a href="http://www.contentquality.com/..." title="508 Accessible">508</a> | <a href="http://www.contentquality.com/..." title="Web Accessibility Initiative Compliant">WAI</a></div>
Default front page: http://bellascena.com/node

You'll note that I put actual HTML into the Mission and Footer fields. Yup, you can do that.

In a little bit, we'll actually be changing the default front page, but for now, we'll leave it as is.

Go ahead and save your configuration after you've put in your values.

Date and time

Head on over to the 'Date and time' section under Administer > Site configuration > Date and time. Set your correct time zone, and any custom formats you'd like.

Creating users and setting permissions

Since we're not really building a heavily user-based site, we'll setup our user system for the administrator only. We'll also need to turn off user registration so no one is allowed to do so.

Go to Administer > User management > User settings. I'm going to select 'Only site administrators can create new user accounts.' to disable user registration. I'll also ignore the e-mail customizations since we won't need them.

Now we need to setup the site administrator. Note the difference between the admin user we create and the user account you use to setup and build the site. The user account that you use, the very first one we setup, has 'super' privileges to do anything. The admin user we'll create for our client will be subject to permissions we set.

Go to Administer > User management > Users. Select 'Add user' and fill out the form. You probably don't want to notify the client of the new account automatically, since the site isn't done yet :). The user I created is 'admin'. You can go to 'List' and see both users, the one you just created, and your user account.

We need to be able to distinguish between our administrator that we just created and anyone else who we might create accounts for in the future. Thus, we need to create a new role, the 'administrator' role. Go to Administer > User management > Roles. At the bottom of the list of current roles, you'll see an input box for a new role. Create a new role titled 'administrator' and click 'Add role'. Now we need to assign that role to our user that we just created, and to ourselves, of course :). Go back to the users list, and for each user, click 'edit', then under the 'Roles' section, check the 'administrator' box, and save.

Google Analytics

So now we get to start playing around with some real content. The first thing I did when starting the site was to register the site with my Analytics account. If you don't use Google Analytics, you can skip this part, but I highly suggest it.

The easiest and most sensible means to get Google Analytics on our site is to use the Google Analytics module. Go ahead and download a copy to your computer. Within the download, you'll find a folder titled 'google_analytics'. We need to get that into our Drupal installation. Create a new folder within '/sites/all' titled 'modules'. Place the 'google_analytics' folder within the '/sites/all/modules' folder. Upload the new folders to your server.

The first thing we need to do when we upload a new module is to enable the module within our Drupal system. Navigate to Administer > Site building > Modules. At the bottom of the list, you should see our 'Google Analytics' module. Wahoo! Go ahead and check that there box and click 'Save configuration'. Yeehaw.

Now, the Google Analytics module has some advanced features that are probably beyond our scope here, but you can read about them at the module homepage. We just need to configure the module to use our unique Google Analytics User ID. Visit Administer > Site configuration. You'll see a new menu option there, titled 'Google Analytics'. Go ahead and click on it. You'll see the field for your User ID. Enter your User ID and click 'Save configuration'. You can safely ignore the other settings for now, as mentioned above.

There, all done! Our first module is installed and configured correctly. In fact, since the default theme makes use of common Drupal theming techniques, the code is live on all of your pages. If you visit your front page and check the source, you'll see it!

Navigation - Introduction

At some point, we'll need to tackle the navigation structure for our new site. The BeeEss navigation schema is as follows (with links to the current site sections in action):

As you can see, we have three different types here: static, teaser views, and the contact form. The photo gallery solution I used for the site is not affiliated with or integrated into Drupal at all. I'll get into the details of why I chose an external solution (and what I used) a bit later, but for now we can ignore it.

For now, we won't actually build the navigation menu items yet, because we're going to create them on the fly when we build the content. We'll revisit navigation structure a bit later.

Static pages

Before we bang out the few static pages our client needs, we need to tweak a few settings to make our URLs b-e-a-utiful. In a default Drupal install, when you add a node, be it a page, story, or anything, the URL to that node is automatically created like so:

http://domain.com/node/4

Unfortunately, that's not very useful for search engines. Search engines enjoy URLs that are relevant and descriptive, such as this:

http://domain.com/cat-jumps-over-cows-moon

Luckily, Drupal provides a few pieces of functionality that allow you to do just that easily and seamlessly. Drupal's Path module is a core module that comes with every Drupal install. The Path module allows you to create 'URL Aliases' which essentially map custom URLs to nodes within the system. This is fine and dandy for a web-savvy developer who is hip to the SEO juicyness, but what about the content that your client will create on the fly? Well, for that, we need a more automated system.

Pathauto

Enter Pathauto. Pathauto is a nice little module that'll take care of the oh-so-tedious task of manually choosing URLs for your nodes to be accessed by. It does this automatically based on an algorithm that computes the URL from your node title. Long story short, the content author need not know anything about it. Splendid. So let's grab that. Download a copy of the module to your computer. Unpack it, and you'll find the 'pathauto' folder with all the guts inside. Upload the 'pathauto' folder to your '/sites/all/modules' folder just like we did with the google_analytics module if you were paying attention above. Upload the goodness to your server, and revisit the modules page at Administer > Site building > Modules. Scroll down and find the Pathauto module we just uploaded. Crap. Looks like we can't enable it yet because we need a module that Pathauto depends on. That's the Token module. I really don't know much about the Token module, but according to the project page:

Tokens are small bits of text that can be placed into larger documents via simple placeholders, like %site-name or [user]. The Token module provides a central API for modules to use these tokens, and expose their own token values.

Since Pathauto is insisting that it really wants Token, go ahead and download the Token module and upload into your '/sites/all/modules' directory as usual. I did - it wasn't so bad.

Now go back to the modules admin screen and reload. You'll see the Token module popup right underneath the Pathauto module. Enable them both, and click 'Save configuration'. Doing so notifies me that I also need to enable the Path module, which is a core module already available in our installation. Click 'Continue' to have Drupal enable the Path module in addition to the Token and Pathauto modules.

Now, when Pathauto is first enabled, it's comes pre-configured for 'optimal' performance with most Drupal installations. We will, however, want to make one modification. When Pathauto generates a URL, we want it to be reflective of what type of content that node is. For example, if Pathauto is building a URL alias for a 'News' content type, we'll want the URL to be something like '/news/nice-friendly-url-to-content', rather than just '/nice-friendly-url-to-content'. Go to Administer > Site configuration > Pathauto. Open up 'Node path settings'. In there, you'll see 'path patterns'. The default path pattern is set to 'content/[title-raw]'. You can keep that as is, but for 'Pattern for all Page paths', set it to '[title-raw]' (without the quotes). When we create other content types, we'll modify these settings accordingly.

WYSIWYG Editor

We're almost ready to start adding static pages of content. Head on over to Create content -> Page. At this point, put yourself in the client's shoes and try and invision what they need to do at this step. Ideally they really only need a 'Title' and a 'Body'. That's about it for a Page. It would be nice, however, to have a WYSIWYG editor for the client to be able to easily manage things such as bold text, hyperlinks, etc. There are a few options for Drupal, including FCKeditor, TinyMCE, BBCode and WYMeditor. I'm a big proponent of what the guys behind WYMeditor are attempting to do, but it's still in its infancy and I'm not convinced it's ready for a production site (as mentioned on the product page as well). TinyMCE and FCKeditor both take the approach of 'everything but the kitchen sink', with the option to include the kitchen sink. We don't need the kitchen sink. Go ahead and grab the BBCode module, upload it, and enable it. You should be able to figure it out by now ;). If not, read the Google Analytics part above.

So you've got it installed. Go to Administer > Site configuration > Input formats. Input formats are something we haven't touched on yet. They are essentially a grouping of filters that can be used on node creation and editing. BBCode's editor is really just a 'filter' that we can assign to an input format. Go ahead and create a new input format titled 'BBCode'. So here's the first showing of our 'administrator' role that we created a while ago. Be sure to select the 'administrator' to be able to use this input format. I made this mistake the first time I we through this, and it wasn't fun debugging why the heck it wasn't working. So yeah, do that. For 'Filters', choose 'BBCode', and click 'Save configuration'. You'll see your new input format show up in the list. Go ahead and set our new BBCode input format to 'Default' so our client won't have to select that format each time. It's also worth noting that you can disable the 'Filtered HTML' format that we'll probably never use for this project. To do that, click 'configure', then uncheck both users and save it. Note that the super-user can always use any of the formats listed here, even if they are disabled for any specific roles. This will come in handy when we build a static page that has all sorts of fun stuff in it.

So now our input format is set to BBCode, but we need some way to provide a GUI for the user, rather than having to resort to the BBCode documentation every time. Fortunately, there is the Quicktags module. Unfortunately, at the time of this writing, the 'stable' release of this module is actualy unstable. There is a bug in the code that was fixed in the development trunk. Go ahead and grab the latest development snapshot for this module. You can find it here: http://drupal.org/node/13362/release. The correct version to download (at this time) is 5.x-3.x-dev. Go ahead and download, upload and enable the module. Also enable the QuicktagsPlus module that comes with Quicktags. That'll add some additional buttons that we can use. Head over to Administer > Site configuration > Quicktags for configuration. I'm content with having Quicktags show up everywhere, because I'm not going to allow or surface comments for our site, but if you want to change this, you can.

Creating Pages

Now we're ready to add our first static page. Visit Create content > Page. Now, I need to create the 'Company Info' page for our client. The page looks like this (in completion): http://bellascena.com/company-info. It's pretty basic. Go ahead and enter the the title of the page, and the body. Try and replicate what I've done here. The 'Management and Principles' heading should be an H1 tag, and the names of the managers should only be bolded. As you can see, BBCode makes easy work of this. Easier than Word if you ask me. Now, without modifying anything else (read: simple), click 'Submit'.

Sweet mother of molasses, we have our first 'Page'. Better yet, check the URL of your page, it should be '/company-info'. If so, Pathauto is working stupendously. Win.

So it really is almost as simple as that for creating pages, with one exception. Since these 'Pages' will be main sections of our website, we want them to be accessible via our primary navigation. Go back to the page we just created and click 'Edit'. Open up 'Menu settings', enter the title (Company Info), the description (which will be used for alt text - I used 'Company information about BeeEss') and the parent item (Primary links - at the bottom). Don't worry about the weight for now, we'll move things around once we've got our main items in our navigation. Save the page. If you look at the top of the site where the default location of primary links reside, you'll see our new menu item. Nice!

Homework: repeat the above steps for creating pages and menu items for the following pages:

Also, create a 'Home' page using the same techniques. For the title, use 'Home', and for the body, just use some simple HTML and set the input format to 'Full HTML'. We'll perfect this later.

News Page, and News Content Types

Our client needs an area of the website to be able to post latest news about what they're up to. A traditional 'News' section is in order. It's not completely apparent how to accomplish this easily in Drupal, though. The key here is the Views module. The Views module makes it possible to generate dynamic 'views' of certain content types with all sorts of configurations. Luckily, what we need Views to do for us is extremely basic, and thus easy to setup.

Grab the latest version of the Views module from Drupal.org and upload to your server. The module itself comes with many different components. Enable each of the Views modules, with the exception of the 'Views Theme Wizard'. We won't need that. So, you'll be enabling 'Views', 'Views RSS' and 'Views UI'.

Before we can setup a view of content types, we need to actually create that content type. Navigate to Administer > Content management > Content types. We need to add a new one, so select 'Add content type'. For a news item, we really only need a title, the body of the news item, and the date / time when the news was posted. Luckily, that's exactly what a basic content type provides. I entered the following for our news content type:

Name: News
Type: news
Description: A news item.

I left the rest of the fields untouched, with the exception of 'Promoted to front page'. Uncheck that one, then click 'Save content type'.

Now that we have a new content type, we'll want to modify our Pathauto settings to reflect it. As mentioned, when we post a 'news' item, we'll want the URL to be something like '/news/some-news-item'. Head over to the Administer > Site configuration > Pathauto section and open up the Node path settings. You'll see 'Pattern for all News paths'. Enter 'news/[title-raw]' without the quotes. Save the configuration.

Create some mock news items so we can test our setup. Go to Create content > News. Create about 3 or 4 news items. All you need is Title, Body and to ensure that 'Published' is selected (which it is by default). Make the body of a few of the news items pretty long so we can test the 'teaser' view versus the 'full' view of the news item a little later. Confirm that the URL reflects our Pathauto setting (/news/news-item-title).

Now that we've got some news items in our Drupal system, we need to surface them somehow. Ideally, we'd have a 'News' page that lists 'teasers' of each news item, with links off to each individual news item for the full view. Go to Administer > Site building > Views. You'll see a few default views that are created when you enable the Views module. I'm going to disable each of them, as we'll be creating our own. Select 'Add' to add a new view. Name your view 'news' and allow access to all roles. Views can be configured as either 'Pages' or 'Blocks'. Since we want our users to be able to access the news listings via a page, we'll setup our view as a page. Open up the 'Page' fieldset, and select 'Provide Page View'. We want our view to be accessible at http://www.bellascena.com/news, so for the URL, enter 'news' without the quotes. Change the 'View Type' to 'Teaser List'. Open the fieldset 'Empty Text'. This is where we'll define our content of the page should there be no 'news' items to display. I entered 'Sorry, there are no news items yet.' Under the 'Menu' fieldset, we definitely want to create a menu item for this view, so our users can access the News page via the main navigation. Check 'Provide Menu', and enter 'News' for the Menu Title.

Continuing on down the new view form, open up the 'Fields' fieldset. We want to add three fields in total: Title, Body and creation date / time of each news item. You'll find these as 'Node: Title', 'Node: Body', 'Node: Created Time'. Add each of those. Next comes filters. We need to filter which nodes the view will show by whether or not the node is of type 'News'. Thus, add the filter 'Node: Type', and set it to 'Is One Of: News'. Now we need to select how our nodes will be sorted. Open the 'Sort Criteria' fieldset. Add 'Node: Created Time' as a criteria, and set it to 'Descending'. Click 'Save' to save the view. All that's left is to set the view to also provide an RSS view of the node listing. Open the 'Arguments' fieldset, and add 'RSS: RSS Feed Selector'. Set the default to 'Display All Values', and save the view.

Navigate to www.domain.com/news, and you should now see your listing of news items! You should also have a nice RSS feed at www.domain.com/news/feed. The only thing left to do is move the Menu item under the corresponding parent item. Head to Administer > Site building > Menus, and edit the 'News' item. Change the parent item to 'Primary links'.

Contact Page

So the last 'page' that our client needs is a contact form. It would also be nice to put his address and contact information on that page as well. Drupal's default installation comes with the 'Contact' core module. Go to Administer > Site building > Modules and enable the 'Contact' module under the 'Core - optional' fieldset. Then head over to the Administer > Site building > Contact form. We'll need to setup a default category, or even multiple categories if we so desire. Select 'Add category' and enter the category name, recipients, 'selected' to 'Yes', and submit. I used 'General Information' for the title of my category since I'll only have one (it won't appear as an option if you've only got one). Now we need to enable access to the contact form to all visitors to the site. Go to Administer > User management > Access control, and enable 'access site-wide contact form' for all. If you visit www.domain.com/contact, you'll see the new form! Now we just need to get it in our primary navigation. Go modify your menu and create a new menu item for the contact page. You'll need to add a new item.

Navigation - Organization

We're all done adding items to our navigation, but we need to organize them. It's pretty simple, but also a tad tedious. Navigate to Administer > Site building > Menus. For each 'Primary links' menu item, select 'edit' and set the appropriate weight. I'm setting mine from 0 -> 5 (left to right).

Photo Gallery - What Happened?

So why didn't I use Drupal for my photo gallery solution? Well, there are several reasons. First off, the final photo gallery looks like this. The photo gallery I ended up using is ZenPhoto, and I've used it before.

Drupal does alot of things well. It manages all sorts of content very well, integrates great caching features and a bulletproof user management system. But photo galleries are not something Drupal is very well known for. My main concern was the UI for managing many photos and galleries. I have yet to find a very robust and clean photo gallery management solution for Drupal.

I've used ZenPhoto for a while now, and find it to be the best out-of-the-box solution for a very simple yet functional photo gallery solution. I commend the guys working on it. The system was built with modularity, simple styling techniques, caching, thumbnail generation and stupid-easy gallery management in mind. Styling a ZenPhoto system is simple. By the way, I'm not affiliated with them at all, but if you're in the market for a nice photo gallery solution, check them out.

Performance Tweaks

For the most part, our site's content structure and functionality spec is done. Now let's speed it up. Drupal has some excellent caching tools available, and they're very easy to use. Head over to Administer > Site configuration > Performance. There's quite a bit going on behind the scenes of Drupal's caching system, but all you need to know is how to turn it on and off, for the most part. You can safely enable 'Page cache', so go ahead and do so. After you log out of the site with page caching enabled, you will instantly notice a significant improvement in page load times.

You can also experiment with the CSS compression on that page. I always run my production sites with 'Aggregate and compress CSS files' enabled, but you may experience issues with this setting. If you have PHP safe-mode turned on (like with a default hosting platform with Media Temple), you'll need to turn it off before you enable the setting.

So now things are spiffy fast.

Conclusion

What's my conclusion? This blog post was way, way, way too long. So if you made it this far, you are a brave soul, and you should have a pretty functional site at this point. I commend your patience and invite you to sit in for the third part of this series coming in a week or so, titled 'Template Theming, Integration and Finishing Touches'. As always, feel free to leave questions or comments. Thanks!

Continue on to the third part: Part III: Template Theming, Integration and Finishing Touches.