Create a Simple Portfolio Website and Blog with Textpattern

*** UPDATED: The original zip file was missing a few important files. Please re-download the zip file to get all the files referenced in this tutorial. ***

Why Textpattern?

Okay, I will be the first to admit that when I first started with Textpattern, I was in way over my head. I had never worked with a CMS before, and I wasn’t an expert with CSS. I had stumbled upon a beautiful portfolio website by another web designer, and I noticed in the footer that the website was built using Textpattern. I thought to myself, if this designer can build a dynamic portfolio website using Textpattern, surely I can too, right? So I made it my mission to learn and master Textpattern. I learned the hard way, since I didn’t know anyone who was familiar with it (Wordpress always seemed to be the CMS of choice). However, Textpattern has an enormously helpful community and many helpful articles, blogs, and forums where other users were generous enough to share their tips, tricks and plugins. Textpattern has now become my CMS of choice as I have found it to be undeniably powerful and flexible, and it doesn’t require any knowledge or experience with PHP (not to mention, it’s free and open source). Once you wrap your head around the basics, you can bend Textpattern to your will quite easily. Check out the publishing features on the textpattern website.

Getting started

This tutorial assumes that you have a fairly strong understanding of HTML and CSS, however I am using an adapted version of Google Blueprint CSS to keep things extra simple. We will be building a very simple portfolio website with a blog component. I will continue to add articles which will build on textpattern’s functionality, but for now I am stripping a lot of Textpattern’s defaults, which can be quite confusing if you’re not sure about the syntax.

Head over to the textpattern website to download the latest version. Follow the detailed install instructions.

You will also need the files I provided in this zip file:

Download zipped archive

Login to your site, and you should see something like this:


You will notice that Textpattern has 4 tabs at the top: content, presentation, admin, and view site. Go to your admin tab, and check your diagnostics to make sure that there are no errors in your installation. If all checks have passed, head over to your preferences, and change your site name and slogan (even if you choose for these not to appear as is, you should change them to be relevant to your own site). It is a matter of personal preference, but I like to change my permanent link mode to section/title, as I like the way it appears in my url. Since this is a beginner tutorial, I would recommend leaving the other settings as is until you are more comfortable with Textpattern.

In the Textpattern handbook, it is recommended that you code your site in HTML and CSS before building it on Textpattern. I tend to build my sites live within Textpattern because I find the textpattern tags and plugins can achieve what I want much faster than coding it by hand. It’s really a matter of personal preference.

What I am going to do is STRIP AWAY the Textpattern defaults, and simplify things a little bit. Once you get more comfortable with textpattern, you can begin to add in more functionality, but for the purposes of understanding how textpattern works, I think the defaults are a bit overkill when you’re learning.

In a nutshell

In a nutshell, textpattern works by posting articles (think of articles as your main content) to sections (main navigation) of your site. Each section is associated with a page template. The pages tab under Presentation is where you dictate the HTML structure of your page. This is where your html combines with txp tags to create the functionality of your templates. The style tab under presentation is where the css resides. Forms are the most powerful part of textpattern; they tell an article how, when, where, and why to appear! More details on forms below.

Set up your sections

Think of sections as the main navigation of your site. In this example, we’ll use about, work, blog and contact. There is no need to create a “home” section, as the “default” section IS the home section, and you will notice that textpattern already has an about section by default. So create a work, blog, and contact section. I tend to leave the “articles” section that is there by default, and I use it to post my articles that appear only on the homepage but nowhere else. For the about and contact page, I tend to select NO for the setting: “on front page” , since the homepage can display articles from all sections, and I do not want my contact page to appear on my homepage.

Install your plugins

There are a number of plugins that are incredibly useful that I tend to install by default each time I create a new site. In the download files I have provided a plugin folder where you will find a number of txt files that contain the plugins you will need for this tutorial. Open the txt files one by one, and install the plugins by going to your Admin > Plugins tab. Just copy and paste the text into the field, and hit upload. You will see a preview of the plugin. Scroll down and click Install. You will then see your plugin title, author, and description. By default, the plugins are NOT active until you click “no” under active to switch it to “yes.” Do this with all of the plugins provided in the plugins folder.

Create your forms

Forms work in one of two ways:

1. As a reusable snippet of information.

Your header, footer and navigation are likely to be the same on every page, so you would create this as a form, which you would then call into your page template.

An example of this type of form would be the header form, which you will find in the forms folder of the tutorial download. In your textpattern backend, go to Presentation > Forms, and create a new form. Call it header, and choose “misc” for the type. Copy and paste the following code into the body of the form and save:

 <div id="head">
<h1><txp:site_name /></h1>
<txp:section_list wraptag="ul" break="li" include_default="1" default_title="home" sections=", about, work, blog, contact" active_class="active"/>

What this does it creates a div with an ID of head, uses your h1 tag to call your site name, and creates your main navigation. <txp:section_list /> creates a list of all the the site sections. What I have done is narrowed the selection down so it just calls the default section (while naming it “home”), the about section, work, blog and contact. It will wrap the entire list in a “ul”, and wrap each individual section with a “li”. It will also automatically add a class of “active” to the current section’s li. If you want more flexibility with your menu, you can always hard code it with HTML, however, this <txp:section_list /> tag is usually all you really need. By default, the section_list ul is assigned a class of .section_list.

2. It tells an article how to behave

One of the most important tags in your page template will be the <txp:article /> tag.

The following snippet:

<txp:article form="single" listform="default" />

basically means: display the article using the form named “single” if you are on an individual article page, and using the form named “default” when you are displaying a list of articles.

In your Presentation > Forms, the “single” form could look like this: (which would just display the title and the body of the article)

 <h3><txp:title /></h3>
<txp:body /> 

while the “default” form could look something like this: (which would display the title, and excerpt, with a link to the full version of the article)

 <h3><txp:title /></h3> <txp:excerpt />
<p><a class="more" href="<txp:permlink />">read more</a></p> 

A list of the most basic and useful forms are provided to you in the forms folder in the download for this tutorial. Create all of them in the Presentation > Forms. If you notice that some of the forms already exist, just override the textpattern defaults with the ones i’m providing. You should have the following forms (in brackets is the “type” you must select for the form):

  • portfolio_listing (article)
  • portflio (article)
  • intro (article)
  • single (article)
  • subnav (article)
  • article_listing (article)
  • default (article)
  • head (misc)
  • foot (misc) – make sure you add your own copyright info
  • meta (misc) – make sure you add your own meta data in this form!
  • excerpt (article)
  • (article)

Set up your page templates

I have created very simplified versions of the textpattern defaults, which you can build upon as you get more comfortable. In the Pages folder, you will find 3 files: default.html, archive.html and home.html. Override the textpattern defaults with the ones I am providing to you. Make sure you go back to your sections, and tell the default section to use page home, the blog page should use archive, and the rest should use default. You must hit save after each change, you cannot change multiple sections at once.

Set up your style

I have created a master style sheet based on Google Blueprint CSS and incorporates some of the Textpattern defaults. Copy the content from the screen.css file provided in the Styles folder and paste it into your default styles tab under Presentation > Style.

Add your portfolio

I have created this portfolio with certain defaults, to help you get a feel for how textpattern works. Once you understand the basics, you should feel free to use your own image sizes, css, etc. As a basis, portfolio images should be sized to maximum width of 620px. Upload a few of your own images (i’ve included a few placeholder images) through the content > images tab. Specify a size of 300px wide by 200px tall for your thumbnail. Click “crop” to avoid the image being squished to fit your dimensions. Hit save once you are finished. There are additional plugins which are fantastic for offering advanced image editing; if you are feeling adventurous, I highly recommend this plugin: ebl-image-edit, which will allow you greater flexibility for creating thumbnails and cropping, etc. Once you have uploaded an image, you will notice that Textpatern automatically assigns the image an id number. Take note of the id number, as that is how you will refer to your images in the future.

Head over to the Content > Write tab to write your first article. Give it a title, put a description in the body. On the left, click “advanced options” and under article image, enter the id #’s (separated by a comma) of the images you wish to be associated with this article. Then, assign the article to the “work” section. When you are finished, hit “publish.” Continue to write your articles, assigning your images to each article. When you have written a few articles, you should click “view site” in the top right of the textpattern window. I tend to leave one tab with the textpattern backend open, with the live site in another, so I can easily refresh and see any changes (or errors!)

You should see something like this:


This is basically the work page in its “listform.” If you click on any of the thumbnails or article titles, you will see the “individual article,” which should look something like this:


If you take a look at the code in the page template for work, you will notice this textpattern tag:

 <txp:article listform="portfolio_listing" form="portfolio" sort="posted desc" limit="30" /> 

If we analyze the form portfolio_listing, it looks like this:

 <div class="span-8">
<txp:permlink> <txp:upm_article_image type="thumbnail" limit="1" class="border"/>   </txp:permlink>
<h3><txp:permlink><txp:title /></txp:permlink></h3>
<txp:excerpt />

This basically tells the page to list articles in the form of a div with a class of .span-8, which contains the “image associated with the article”, in the form of a thumbnail, limit it to 1 image, and link the image to the full version of the article. Underneath the image is the “title” of the article in the style of h3, which also links to the full version of the article. Beneath that, show the excerpt associated with that article.

If you take a look at the form “portfolio”, you should see this:

<div class="span-8">
  <h3><txp:title /></h3>
  <txp:body />
<div class="span-16 last">
   <txp:upm_article_image />

This basically creates a div with a class of .span-8 which contains the title and body of the article. Beside it floats a div with a class of .span-16 last, which contains the images associated with the article. Should you wish for the title to appear above the images on the right, you would simply move the <h3><txp:title /></h3> over to the div with the class of .span-16. These forms basically determine the layout for your articles.

A note about article and article_custom

You will notice in the home.html template, that there are two different ways to call articles: <txp:article /> and <txp:article_custom />. It took me a while to wrap my brain around the difference between the two, but here is how it works:

<txp:article /> will call your full article in whatever form you tell it to use. It is section-specific, which means it will automatically call an article from the section you are currently visiting. You must always have an article tag on your page.

<txp:article_custom /> Think of this as a LIST of your articles, in whatever form you tell it to use. Using this tag, you can call articles from ANY section into a page. For example, one the homepage, I am using the article_custom tag to display a snippet from the work, blog, and articles sections. In the archive template for example, on the left-hand side, I am using article_custom to display a full list of all articles posted to the blog page (in the form of subnav), and I am using the plugin “rvm_if_this_article” to automatically detect the current article and make it active.

Create your contact page

You can use the plugins provided (zem_contact_lang and zem_contact_reborn) to create a contact form on your contact page. If you have already installed the plugins provided, and wish to use the contact form, copy and paste the following details into the body of a new article. To avoid formatting with textile, (textile will automatically render things in paragraphs) put a space before each line. Putting a space tells textpattern to format as is, with html, not textile.

<txp:zem_contact to="[email protected]" label="">
<txp:zem_contact_text label="Name" break=""/>
<txp:zem_contact_email label="Email" break=""/>
<txp:zem_contact_textarea label="Message" rows="10" cols="23" break=""/>
<txp:zem_contact_submit label="Send" />

In the excerpt, paste any information you wish to be on the left hand side of the page, such as links to your facebook, twitter, or other profiles. And/or you could place an image here; it’s up to you. Assign the article to the “contact” page, and publish.

Create your about page

Create a new article for your about page. In the body write your bio. In the excerpt, place your photo (or other additional information you wish to provide). In order to call an image, you would write the following: <txp:image id=”#” /> and of course, replace the # with the proper image id number. Assign the article to the about section and publish. If you want to change how this page is displayed, you can edit the form named about.

Create your blog page

There are a million and one ways to organize your blog, and I am just demonstrating a very simplified way, since this is probably a whole other tutorial.

Write your blog article. Add an excerpt (usually the first paragraph of your blog). Publish it to your blog section. (You can feel free to create categories, and assign your article to categories, but I won’t get into how to navigate by category in this tutorial- stay tuned). When you click on the blog page, you should see a list of your articles in the form of a Title with an h3 style, followed by the articles’ excerpt. You can click on the title to reach the full version of the article. You will notice a list of your blog articles on the left. I have limited the page to 10 articles on the listing page. When there are more than 10 articles, the page will display a link on the bottom that says “older” and “newer”. This page will always display the most recent articles first. Should you wish to change the order, you can change the timestamp of the article. Click on the article you wish to edit, and on the bottom right you will see a link that says “more.” Click that and you will notice that you can manually reset the timestamp. Hit save. Obviously, this is somewhat of a temporary solution for a blog, since having many blog postings would create quite a long list on the left. Stay tuned for an article on navigating your blog by category. If you wish for comments to be allowed, you must turn them “on” in the actual article itself. On the right hand side of the article page, you will see “allow comments.” Choose yes or no.

Bring it all Home

Now it’s time to create your homepage.

Create an article that will be an introductory paragraph on the homepage. We are using the form “intro” on this article, so it won’t display the title. If you want this article to use a title, change the form in the tag to “single” instead of “intro”. To clarify, you are looking for this tag in your home page template:

<txp:article_custom status="sticky" sort="posted asc" form="intro"/> 

Otherwise, use the heading of h3 in your body by typing h3. (with a space after the period) before your copy. (As opposed to wrapping your copy in <h3> tags) On the right, choose a status of “sticky”. We are making this article “sticky” because we don’t want it to be affected by newly written articles- it is more or less “static” content. Your work articles will always be displayed with the status of live, and the homepage will always display the most recent work.

You will notice in the “home” page template, that there is this tag: <txp:image id=”3″ />. Replace this number with the # of the image you want to appear here. The size is set to 940px wide by 350px high. Upload an image of that size through your images tab, and then replace the number in that tag with the appropriate id #.

Also on the homepage is a snippet from the most recent blog posting. If you want to change how the blog appears, you must edit the form “article_listing”. Keep in mind, this will change how your blogs appear on your blog page as well. If you wish for your blog to appear differently on the homepage than it does on the blog page, simple change the form used in this tag on your home template form:

 <txp:article_custom form="article_listing" section="blog" limit="1" sort="posted desc"/> 

Try it out!

I’ve provided templates/forms/css to you to help simplify some of Textpattern’s funcionality, but its really up to you to make it work how you want it to. It is a very powerful CMS, and I would recommend looking through some of the textpattern tags to see what is available. There are many powerful “if” statements that provide even greater flexibility. Feel free to change any of the pages/forms/html and css I have provided to tailor it to your own needs. There are tons of resources out there to help you understand how to use it better. I highly recommend setting up a test site where you can play freely and experiment. There are so many different ways to work with textpatterns functionality; this is just the tip of the iceberg! If you think you might want to consider textpattern as your cms of choice, I recommend checking out the following sites:

Stay tuned for articles on how to build an extremely easy to update gallery page with thumbnail and captions, as well as category-based blog navigation, and easy nested sub-menus with automatically detected active class.

This is my first official “tutorial”, so if anything is unclear, feel free to post your comments/questions in the comments below, and I will do my best to answer any questions. I am also open to any feedback you may have as well, or suggestions for future articles.

Marie Poulin is a freelance graphic designer specializing in interactive design & strategy. She builds clean, usable websites using Textpattern, HTML and CSS. Twitter


If you liked this article, please help spread the news on the following sites:

  • Bump It
  • Blend It
  • Bookmark on Delicious
  • Stumble It
  • Float This
  • Reddit This
  • Share on FriendFeed
  • Clip to Evernote