Static Site Generation with Sculpin

user news

Static site generators such as Jekyll, Sculpin and Octopress are a great way to make very fast static HTML sites. Admittedly they do have their limitations, but work really well for simple sites which do not require a database.

I had built a couple of generated sites with a Ruby static site generator called Jekyll but now I wanted to try a PHP equivalent. I came across a tool called Sculpin and it made sense to use it as I was already used to using Composer and Twig which are used by Sculpin.

Sculpin allows you to very easily set up the site structure using YAML configuration. The content can then be added with Markdown, or Twig. The templates can then be easily manipulated with the Twig template engine.

Managing the Assets

I chose to manage the assets for the project using Gulp, Bower and I managed the Node dependencies with NPM.

I installed the Gulp modules with NPM and I installed Bower globally as it's used in other projects on the server. I then installed the SASS framework Bourbon/Neat, Fontawesome and the JS with Bower.

I set up a Gulpfile to do a few tasks with the assets as I needed the SASS to be preprocessed and minified, JS uglyified and some files copied into new locations.

My Gulpfile.js

var gulp = require('gulp');
var sass = require('gulp-sass');
var notify = require("gulp-notify");
var bower = require('gulp-bower');
var uglify = require('gulp-uglifyjs');
var gp_concat = require('gulp-concat');
var config;
config = {
   sassPath: './sass',

   bowerDir: './bower_components',
   assetsPath
: './source/assets'
}
gulp.task('styles', function() {
    gulp.src(config.sassPath + '/style.scss')
        .pipe(sass({outputStyle: 'compressed'})
        .on('error', sass.logError))
        .pipe(gulp.dest(config.assetsPath + '/css'));
});
gulp.task('icons', function() {

    gulp.src(config.bowerDir + '/font-awesome/fonts/**.*')

        .pipe(gulp.dest(config.assetsPath + '/fonts'));

});
gulp.task('images', function() {

    gulp.src(config.bowerDir + '/photoswipe/dist/default-skin/**.*')

    .pipe(gulp.dest(config.assetsPath + '/css'));

});
gulp.task('js', function() {

    gulp.src(
        [
            config.bowerDir + '/jquery/dist/jquery.js',
            config.bowerDir + '/glidejs/dist/glide.js',
            config.bowerDir + '/photoswipe/dist/photoswipe.js',
            config.bowerDir + '/photoswipe/dist/photoswipe-ui-default.js',
            'js/app.js'
        ]
    )

    .pipe(gp_concat('core.js'))
    .pipe(uglify())
    .pipe(gulp.dest(config.assetsPath + '/js'));

});


gulp.task('default', ['styles', 'icons', 'js', 'images']);

Site Structure

.sculpin (Sculpin composer modules)
app (Sculpin config)
bower_components
js
node_modules
output_dev (Generated dev site)
output_prod (Generated prod site)
sass
source (Template files used to generate the site)
    _layouts (Contains template files)
    _views
    _projects
        tags
            tag.html (template for project tag single)
        tags.html (template for project tag list)
    index.html
    projects.html

 

Configuring Sculpin

Sculpin allows custom page types to be used eg. You may have a types for articles, products, projects or anything else you can think of. For each type there is configuration that can be set including the permalink, layout file, location of the files to be used as well as a few others. Here is the page type configuration I used for a projects type.

 

sculpin_content_types:
    projects:
        type: path
        path: _projects
        singular_name: project
        layout: project
        enabled: true
        taxonomies:
            - tags
        permalink: projects/:filename/


Taxonomies

Taxonomies can be set up for each page type. An example of this would be to set up Tags or Categories which is very easy to do.

Below is an example of a page I could use for a project.

 

title: Page Name
summary: page summary
image: projects/project1.png
color: blue
tags:
    - server side
    - programming
categories:
    - programming

Page content here.....

Vars

Global vars can be added in /app/sculping_site.yml. Example of a few I used are below.

title:Title Text
subtitle: Sub title text
google_analytics_tracking_id: UA-44444444-1

The vars can be used anywhere in the pages, type or template with { site.varname }.

 

Deployment

There are a few ways I could have went about doing the deployment. I had to consider whether I used an automated deployment tool or if I just manually pulled the repo and ran the scripts. I decided to go with Rocketeer which is a PHP based deployment tool, much like Capistrano but written in PHP. The automated deployment is worth using to avoid having to directly access the production server.

The other consideration was whether I run “Sculpin generate” on the production server or locally then commit the generated files. I decided to run on the production server as part of the deployment script.

Another consideration was whether Gulp should run on the server or if it should be done locally and also committed. I also opted for running on the production server.

The final deployment is..

Pull the repo

sculpin install

NPM install

bower installed

Gulp

sculpin generate --env=prod

 

Conclusion

After using Sculpin a few times I decided I preferred using Sculpin over Jekyll. The functionality was pretty similar although I preferred using Twig and I liked the fact Composer was used.

As for static site generators, they are an excellent tool for a developer or someone with enough knowledge to edit the code. I think they fall short when you want to use a database or have a content management system. I also think there may be problems with trying to do a more complex data structure. I will use Sculpin again but probably just for very basic sites.

Author Bio

Scott Pringle - PHP Magento and Symfony developer with 5 years experience.

Comment Form