This is a follow up tutorial to Introduction to Craft CMS. If you're unfamiliar with Craft, I recommend you read part one first. Then, return here and follow our installation and getting started guide.
What Is Craft CMS?
Pixel & Tonic's Craft CMS is a WordPress alternative for development-oriented publishers who want deeper control and more powerful performance from their content management tools. It's also a potential option for consultants and developers to expand their client offerings.
Craft is not a site builder—you need to build out your HTML, CSS and JavaScript by hand incorporating Twig templates. This won't be intimidating for those used to building WordPress themes. For others, unfortunately, there's no official theme or plugin marketplace at this time (though I wouldn't be surprised if one appears in the future). But Craft is built to be exceptionably scalable and offers native features for complex content management relationships.
It's an appropriate choice for small websites but will shine with larger content sites with significant multi-layered, inter-related content.
Craft is written in PHP on the powerful Yii 1.x platform. If you haven't heard of Yii, you can read my Introduction to the Yii Framework at Tuts+. You don't need to know PHP or Yii to use Craft. It's akin to Django-powered CMS tools written in Python.
While you might not have heard of Craft, its developer community is growing fast. Last June, its proposal for a Craft CMS StackExchange site was approved in just five days.
You can view a showcase of sites running Craft here.
In this tutorial, I'll walk you through the process of installing Craft, its demo site, and getting familiar with Craft for building your own site with it.
Installing Craft's On The Rocks Demo Site
First, let's install Craft's On The Rocks demonstration site with sample theme and content. This site also unlocks all of the premium features for testing.
I'm using Mac OS X with MAMP. My local sites run in the ~/Sites directory. Let's clone the Craft demo site from Github:
git clone https://github.com/pixelandtonic/ontherocks.git
Then, let's set the file permissions for Craft's internal directories:
cd ontherocks chmod 777 craft/storage/ chmod 774 craft/config
Next, let's update the latest build of Craft. In February 2015, I used version 2.3.2627. However, you can find the very latest at the "Updates" page on the Craft website..
curl -L http://download.buildwithcraft.com/craft/2.3/2.3.2627/Craft-2.3.2627.zip -o /tmp/Craft.zip unzip /tmp/Craft.zip -d BaseCraft cp -R BaseCraft/craft/app craft/app rm -R BaseCraft && rm /tmp/Craft.zip
Then, I used PHPMyAdmin to create the database:
Click on the ontherocks database in PHPMyAdmin. Then click Import and choose the file in ~/Sites/ontherocks/SQL/ontherocks.sql
:
Then edit the database configuration file with the credentials for your local MySQL database:
nano ~/Sites/ontherocks/craft/config/db.php
/** * Database Configuration * * All of your system's database configuration settings go in here. * You can see a list of the default settings in craft/app/config/defaults/db.php */ return array( 'server' => 'localhost', 'user' => 'rocks_user', 'password' => 'yourpassword', 'database' => 'ontherocks', 'tablePrefix' => 'craft', );
Create a new virtual host with the hostname “ontherocks.dev” that points to the public/ folder.
Edit your /etc/hosts file to resolve ontherocks.dev to 127.0.0.1, if necessary:
## # Host Database # # localhost is used to configure the loopback interface # when the system is booting. Do not change this entry. ## 127.0.0.1 localhost 127.0.0.1 ontherocks.dev
The Craft dashboard is located at http://ontherocks.dev/admin. When loaded, you'll see something like this: monkeys...and eyeballs!
Then, you'll be asked to update the database:
You can log in with the following credentials: Username: admin, Password: password.
The Craft Dashboard
Here's the dashboard—looks a bit like WordPress, huh?
Here's the On the Rocks homepage:
Exploring the Happy Lager Demonstration Site
The nice folks at Pixel & Tonic gave me a pre-release of their new, free demonstration site, which hopefully will be available by the time you read this—clone it here. The new site is called Happy Lager:
The installation steps are exactly the same as we described above for On the Rocks. The Git repository should be located here:
git clone https://github.com/pixelandtonic/happylager.git
Happy Lager makes use of Craft's deeper layout capabilities. Here's a pair of screenshots from the About page:
Below the fold:
Here's the Services page:
Craft's Entries Page
Here's the Entries page in the dashboard with all the content from Happy Lager:
Take a look at the entry types on the left navigation pane: Singles, Channels and Structures. Craft offers more sophisticated, extensible data types than WordPress.
Singles are one off pages that have a unique design such as your site home page. Channels are for entries organized by date, such as a blog or news sections. Structures are for content provided in a predefined order.
The Craft Editor
Here's the edit page. Note the breadth of possible fields which again are customizable, e.g. Title, Featured Image, Short Description, Heading, Subheading, Article Body.
Notice below the fold how the pull quote type offers various layouts in the story flow as does the image that follows (but I couldn't include it all in the screenshot):
This capability is what Craft calls its Matrix, and it allows for more powerful story composition and layout. Each block can have custom fields and custom position, and can be dragged and dropped into place in the flow. Here's a short video showing the Matrix:
Here's the Live Preview—just beautiful. It reminds me of Ghost's Markdown preview which I wrote about in Keeping Up with Ghost 0.5 (Tuts+). Readers may remember I hate Markdown—so I very much appreciate the Craft live preview:
Here's a bit more on Live Preview:
Craft offers easy access to past revisions:
The Craft Media Library
Image assets are organized by group and available on the Assets page:
If you've ever waited for WordPress to load your media page, you'll appreciate how fast Craft is.
Constructing the Happy Lager Home Page
Here's a closer look at the content behind parts of the Happy Lager home page—specifically, this is how it appears when you're editing the content:
Craft uses Twig templates to transpose the structured content elements into web pages:
{# # About template # ------------------- # # Single about template # # #} {% extends "_layouts/site" %} {% block main %} <header class="alt"> <div class="flex"> <div class="g1-flex4 g2-flex6 g3-flex12"> <h1 class="alpha center reverse">{{ title }}</h1> </div> </div> </header> <section class="info-hero alt"> <div class="flex"> <div class="g1-flex4 g2-flex6 g3-flex8 g3-offset2"> {% if entry.infoHeroTopText %} <h1 class="delta reverse center subfont">{{ entry.infoHeroTopText }}</h1> {% endif %} {% if entry.infoHeroBottomText %} <p class="epsilon center reverse">{{ entry.infoHeroBottomText }}</p> {% endif %} </div> </div> </section> <section class="alt"> <div class="flex"> <div class="g1-flex4 g2-flex6 g3-flex10 g3-offset1"> {% if entry.firstSectionHeader %} <h1 class="beta center">{{ entry.firstSectionHeader }}</h1> {% endif %} {% if entry.firstSectionSubheader %} <p class="delta center subfont caps">{{ entry.firstSectionSubheader }}</p> {% endif %} </div> </div>
Section Types
Craft sites are built around the sections we outlined above: Singles, Channels and Structures. Here's a short video that shows section types in more depth:
Here are the sections associated with the Happy Lager demonstration site—notice how each corresponds to the primary navigation bar.
The Homepage and About page are singles. The News and Work page are Channels. The Services page is a Structure.
Of course, Craft also offers categories and tags. Categories help you organize your site's content ahead of time, whereas tags let you create an ad hoc folksonomy based on the content in each of your articles.
Here's a short video describing categories and tags:
Another cool feature Craft offers is the ability to route URL requests by friendly paths directly to specific sections:
Here's the What's On Tap page from http://happylager.dev/index.php/work:
Here's a look at the Services—How It's Made page at http://happylager.dev/index.php/services. It's a structure whose elements have a pre-defined order.
Each of the image boxes is driven by an entry under services. You can change their order of appearance via drag and drop:
Here's an example Twig template for this page:
{% extends "_layouts/site" %} {% block main %} <header class="alt"> <div class="flex"> <div class="g1-flex4 g2-flex6 g3-flex12"> <h1 class="alpha center reverse">{{ title }}</h1> </div> </div> </header> {% for entry in craft.entries.section('Services').find() %} <div class="flex"> <div class="g1-flex4 g2-flex6 g3-flex12"> <p class="delta alt"> <a href="{{ entry.url }}"> {{ entry.title }} </a> </p> </div> </div> {% endfor %} {% endblock %}
And here's the template for each entry. This gives you an idea of how to build Twig templates for your Craft site and what's involved:
{# # Services entry template # ------------------- # # This template gets loaded whenever a Work entry’s URL is # requested. That’s because the Work section’s Template setting is # set to “services/_entry”, the path to this template. #} {% extends "_layouts/site" %} {% block main %} {% set currentUrl = craft.request.getUrl() %} {% set lastSegment = craft.request.getLastSegment() %} {% if lastSegment != 'services' %} <nav class="subnav"> <div class="flex"> <div class="g1-flex4 g2-flex6 g3-flex12"> <ul> {% for entry in craft.entries.section('Services').type('servicesDetail').find() %} <li> <a href="{{ entry.url }}" class="{% if entry.url == currentUrl %}current{% endif %} subfont caps"> {{ entry.title }} </a> </li> {% endfor %} </ul> </div> </div> </nav> {% endif %} {% if lastSegment == 'services' %} <header class="alt2"> <div class="flex"> <div class="g1-flex4 g2-flex6 g3-flex12"> <h1 class="alpha center reverse">{{ entry.title }}</h1> </div> </div> </header> <section class="alt"> <div class="flex"> <div class="g1-flex4 g2-flex6 g3-flex8 g3-offset2"> {% if entry.indexHeading %} {{ entry.indexHeading }} {% endif %} </div> </div> </section> <section> <div class="flex"> {% for entry in craft.entries.section('Services').type('servicesDetail').order('postDate desc').find() %} <div class="g1-flex4 g2-flex2 g3-flex4"> <a href="{{ entry.url }}" class="services-entry-wrap"> {% set image = entry.featuredImage.first() %} {% if image %} <img src="{{ image.getUrl('thumb') }}" alt="image.title"/> {% endif %} <h3 class="center">{{ entry.title }}</h3> {% if entry.shortDescription %} {{ entry.shortDescription }} {% endif %} </a> </div> {% endfor %} </div> {% else %} {% include "includes/articlebody" %} {% endif %} </section> {% if lastSegment != 'services' %} <section class="service-points"> {% for block in entry.servicesBody %} <div class="flex"> <div class="service-point"> <div class="g1-flex4 g2-flex3 g3-flex4"> <h4>{{ block.heading }}</h4> {{ block.text }} </div> <div class="g1-flex4 g2-flex3 g3-flex8"> {% set photo = block.image.first() %} {% if photo %} <img class="" src="{{ photo.url }}" alt="{{ photo.title }}"> {% endif %} </div> </div> </div> {% endfor %} </section> <section class="services-work-entry"> {% set entries = craft.entries.section('Work').limit(1).offset(2) %} {% for entry in entries %} {% set asset = entry.featuredImage.last() %}{% if asset %} <div style="background-image: url('{{ asset.url }}')"> {% endif %} <div class="flex"> <div class="g1-flex4 g2-flex3 g3-flex6"> <a href="{{ entry.url }}"> {% set asset = entry.featuredImage.first() %}{% if asset %} <img src="{{ asset.url }}" alt="{{ asset.title }}" width="616" height="204"> {% endif %} </a> </div> <div class="g1-flex4 g2-flex3 g3-flex6"> <div class="summary-wrap"> <h2 class="callout-border"><a href="{{ entry.url }}">{{ entry.title }}</a></h2> <h3><a href="{{ entry.url }}">{{ entry.heading }}</a></h3> {% if entry.subheading %} <p>{{ entry.subheading }}</p> {% endif %} <p><a href="{{ entry.url }}" class="view-more hero-cta">View More</a></p> </div> </div> </div> </div> {% endfor %} </section> {% endif %} {% endblock %} {% block foot %} {{ parent() }} <script type="text/javascript" src="/assets/lib/shapes-polyfill.min.js"></script> {% endblock %}
Editing Entries
Editing entries in Craft is simple, much like WordPress but with enhanced layout capabilities that you would normally require plugins to accomplish.
Each section can have multiple user-defined entry types. For example, the News section here has two different types of entries: articles and links. Entry types allow you to store different types of content in the same section.
Here's a short video on Entry types:
Now that you have a sense of how site construction works in Craft, let's install a fresh version from scratch.
Installing Craft From Scratch
To install Craft, visit the website and download the codebase. I'm using Mac OS X with MAMP for my local development and testing.
Craft provides detailed installation instructions and links to guides for Mac, Laravel, Heroku and even an automated installation with Composer.
Rename the htaccess file:
cd ~/Sites/craftcms/public mv htaccess .htaccess
Create a symbolic link to your Craft public directory for MAMP:
ln -s ~/Sites/craftcms/public /Applications/MAMP/htdocs/craft
If you run your Craft installation locally from the host names “craft.dev” or “ontherocks.dev”, you will have the option to switch between Craft Personal, Craft Client, and Craft Pro for free, forever.
I created the database via PHPMyAdmin.
Edit the Craft database configuration file for your MySQL credentials:
nano ./craft/config/db.php
Enter your credentials in the fields below:
/** * Database Configuration * * All of your system's database configuration settings go in here. * You can see a list of the default settings in craft/app/etc/config/defaults/db.php */ return array( // The database server name or IP address. Usually this is 'localhost' or '127.0.0.1'. 'server' => 'localhost', // The database username to connect with. 'user' => 'root', // The database password to connect with. 'password' => 'your-password', // The name of the database to select. 'database' => 'craft', // The prefix to use when naming tables. This can be no more than 5 characters. 'tablePrefix' => 'craft', );
Set up write permissions for these Craft app directories:
chmod 744 ./craft/app chmod 744 ./craft/config chmod 744 ./craft/storage/
Visit the local Craft home page and you should see the monkeys again!
Register your initial administration account:
Set up your site properties:
And that's it:
Here's your dashboard again:
Craft is so end-user focused that they include a support contact form on their dashboard home page.
You can find site settings from the navigation bar at the upper right. It sort of reminds me of iOS:
Here's what your default Craft site looks like when you begin:
Yes, Craft doesn't have the WordPress community of themes. For the most part, you have to code your own theme. For the novice, WordPress still has an edge.
On the other hand, you may already notice how fast Craft runs compared to WordPress.
Where to Go From Here?
Certainly, you can begin building your site's sample content, but you're going to need to learn about Craft themes and plugins. Here are a few resources that will help you:
- Craft's Template Overview
- Craft's Introduction to Plugins
- Straight Up Craft's (third party site) Plugin Directory
- Straight Up Craft's Directory of Consultants
- Follow @CraftCMS on Twitter
I encourage you to install Craft and explore its feature set further. I'm excited by the power, control and scalability Craft provides as an alternative to WordPress. I'm also a Yii aficionado and it's great to see a CMS tool built on my favorite framework.
If you'd like to see a follow up series on publishing with Craft, please post a note in the comments. I also appreciate your questions and comments and generally do respond. You can reach me on Twitter @reifman or email me directly.
I also want to give a shout out to Brandon Kelly, owner of Pixel & Tonic, the creators of Craft. Brandon was super helpful in answering my questions and gave me a preview of their new demonstration site which you should be able to access now.
Comments