How to Install PyHPy

Published ,  by

The Project Setup Process

Unlike most software tools, PyHPy is not supposed to be installed globally on your system;  Instead, you should download a local copy of PyHPy into each new project that you create.  This ensures that your projects remain independent and self-contained.  Here are the instructions to create a new PyHPy project:

Step 1:  If Necessary, Install Dependencies

If your system doesn't already have them, you'll need to install Python2.7, GNU Make, and ImageMagick:

sudo apt-get install python2.7 make imagemagick

(If there is sufficient demand, I can update PyHPy with Python3 support.)

Step 2:  Initialize the Project Directory

Let's pretend that we want the new project to be stored at ~/mysite/.  In that case, you'd run:

mkdir -p ~/mysite                # Create the project directory.
cd ~/mysite/                     # Enter the directory.
# Download the latest PyHPy to ~/mysite/pyhpy/ :
curl | tar x

At this point, our project directory has been created and PyHPy has been downloaded into the pyhpy subdirectory.  Next, let's copy the example Makefile and input:

cd ~/mysite/
cp pyhpy/Makefile.example Makefile
cp -r pyhpy/input.example input

That's it.  We now have a functional PyHPy project.

Step 3:  Test the New Project

Use the make command to build the project:

cd ~/mysite/

The above command will produce an output directory, where the results are placed.  For your convenience, a simple web server is included to help you view the results:

cd ~/mysite/
make server   # This will run a local HTTP server on port 8000.

Once the development web server is running, you can view your site at .

After you have confirmed that everything is working, you might want to take the opportunity to check your project into an SCM, like Git.

Out-of-the-Box Functionality

PyHPy comes with an example website (the site you're reading right now), which you might want to use as a starting point for your project.

MarkDown-Powered Demo Blog

The demo blog is generated from a directory of .md posts (written in the MarkDown text format), with matching .meta files for metadata (like Author, Summary, Post Image, Publication Date, and anything else you might want to add).

The demo blog generates a separate HTML page for each post, and shows a list of all the posts, sorted by reverse Publication Date.

If you just want to get some posts online quickly, the included demo blog might be a good starting point -- just create your own .md and .meta files in the /input/blog/ directory, and then run make.


The example site uses FontAwesome, which provides more than 600 vector graphic icons.  View the complete set of icons here.  Here are a few examples:


It's easy to use a FontAwesome icon on your site;  Just include the fa-* CSS classes on your elements.  The <i> tag is often used for this purpose.  For example:

I like to ride my <i class="fa fa-bicycle"></i>!

...would produce this output:  I like to ride my !

Thumbnail Creation

The pyhpy.thumb() function makes it easy to produce thumbnail images.  The demo blog and photo album both make frequent use of this feature.  Here are some examples of how to use it:

<img src="${pyhpy.thumb(self.FS_ROOT(), '/static/blogImg/default.jpg', width=150)}" />
<img src="${pyhpy.thumb(self.FS_ROOT(), '/static/blogImg/default.jpg', height=150)}" />
<img src="${pyhpy.thumb(self.FS_ROOT(), '/static/blogImg/default.jpg', width=150, height=150)}" />

...and here's the output:

Notice that the image is cropped-to-fit if width and height are both specified.

Apache Expires Headers

Expires headers instruct web browsers to employ their most aggressive form of client-side caching.  This caching will reduce the number of requests that are issued to the server, and will dramatically improve your site's load time and responsiveness.  However, when using aggressive caching, you need a way to notify clients when new data is available... otherwise they will continue to use their cached versions and won't notice the new stuff.

The example site comes with .htaccess files that enable Expires headers for all requests to /static/... URLs.  (Note:  This feature requires an Apache web server.)  The pyhpy module defines the pyhpy.url(relPath, mtime) function.  This function is useful for generation of URLs that incorporate a website mount point and a timestamp.  For the following examples, assume that your site will be hosted at (mount point = ""):

Mako Template CodeOutput
<a href="${pyhpy.url('/static/css/home.css')}">...</a><a href="">...</a>
(The '_' value is the filesystem modification time of 'home.css'.)
<a href="${pyhpy.url('/home.html', mtime=None)}">...</a><a href="">...</a>
Since this URL is not underneath /static/, Expires headers will not be used. We can use mtime=None to make the URL prettier.
pyhpy.url()This is a special case. It returns the path of the template that is currently being rendered, without the mount point. For example, "/home.html.mako".

The first example in the above table shows how how easy it is to generate URLs that include the filesystem modification time.  This timestamp helps clients to know when new data is available.  Therefore, you can achieve the best of both worlds: aggressive client-side caching, with convenient ability to publish data updates.

Related Blog Posts: