Skip to content
Timothy Kempf edited this page Feb 20, 2014 · 41 revisions

Solidus sites are primarily composed of views–HTML files enhanced with the Handlebars.js templating language. There are three types of views:

  • Pages - views that represent actual pages on the website.
  • Layouts - views that pages are rendered inside of. Usually used for site headers/footers that appear on every page.
  • Partials - small views that are used inside of other views. Generally used for small modules that are used across pages.

Pages are the most important part of your site as they do the following things:

  • Contain the markup that makes up the actual website
  • Define the site's routes ( /, /photos, etc )
  • Contain the configuration data for each page

======

Creating a Page

Any *.hbs file in /views will be turned into a page by Solidus. You'll want to create a new view for each page on your site, except in cases where you use dynamic segments (where one view might represent many pages).

Here's an example of what a website's /views directory looks like full of pages:

/views
├── example.hbs
├── index.hbs
├── layout.hbs
└── /issues
    ├── {id}.hbs
    └── index.hbs

======

Configuration

Pages have a range of configuration options such as the title, resources, and preprocessor to be used on the page. These configuration options are placed at the top of the file in a JSON object wrapped in a Handlebars comment at the top of the page's markup:

{{!
{
    "title": "Example",
    "resources": {
        "issues": "https://api.github.com/repos/SparkartGroupInc/solidus/issues"
    },
    "preprocessor": "example.js"
}
}}

Here's a list of page configuration options:

option type purpose
title string A way to pass the page title to the **[[layout
name string A generic identifier. Has a multitude of uses (like setting an ID or class on the <body> in a layout).
resources object A group of resource URLs and names. When the page is loaded, the URLs here are loaded and their JSON data is stored in the page context.
preprocessor string The path to the preprocessor to be used on this page. Relative to the /preprocessors directory.
layout string The path to a specific **[[layout

======

Routing

Each page's location in the /views folder directly corresponds to the route that Solidus will generate for it. The rules for page route generation are as follows:

  • Normal Routes - The page's path from /views becomes its route.
  • Index Routes - If a page is named index.hbs, its route becomes that of the directory its within.
  • Dynamic Routes - A route created by using curly braces in its path. The part of the path using curly braces will be converted into a catch-all that will match anything that is not explicitly defined elsewhere.

A few examples:

page path matched routes
/views/example.hbs http://localhost:8080/example/
/views/index.hbs http://localhost:8080/
/views/cats/select.hbs http://localhost:8080/cats/select
/views/cats/{cat}.hbs http://localhost:8080/cats/1, http://localhost:8080/cats/2, http://localhost:8080/cats/etc, etc (but not http://localhost:8080/cats/select)

Unmatched Routes

If a visitor tries to visit a page that doesn't have a matching route, they will be served a 404 page. By default, the 404 is a simple text response reading 404 Not Found, but it can be customized by making a 404.hbs view. This view is different from normal pages in that it cannot be configured.

======

Context

The page context is the data that is passed to the page's Handlebars template when it is rendered. This data includes the page's requested resources and metadata about the page and site. In order to view a page's context directly, just add .json to the end of the page's route (ex: http://localhost:8080/example.json). For index pages, just put .json after the trailing slash (ex: http://localhost:8080/.json).

Here's an example of a typical page context, assuming http://localhost:8080/issues/5?test=true (some parts are abbreviated):

{
    "page": {
        "path": "/Users/sparkart/Repos/example/views/issues/{id}.hbs",
        "title": "Issue",
        "name": "issue"
    },
    "parameters": {
        "id": 5,
        "test": "true"
    },
    "query": {
        "test": "true"
    },
    "resources": {
        "issue": { ... }
    },
    "layout": "layout.hbs",
    "settings": { ... }
}

And an explanation of each property in the context:

property explanation
page Contains data related to the page itself. This notably contains the name and title properties from page configuration.
parameters If the page has a dynamic route or uses a querystring, the values passed will appear here.
query If the page has a querystring, the values passed will appear here.
resources An object containing the data fetched from the resources defined in the page configuration.
settings Internal settings used by the server.

Using the Context

Solidus views use Handlebars and Handlebars Helper to render data from the context in pages. If you have the following context:

{
...
    "resources": {
        "blog": {
            "posts": [{
                "title": "My blog post!"
                "body": "This is an example blog post."
            }, {
                "title": "Another blog post",
                "body": "It isn't a blog until you have two posts."
            }]
        }
    }
...
}

You can list out your blog posts with this view:

<html>
<body>
    <!-- use the resources.blog context within this block -->
    {{#resources.blog}}
    <ul id="posts">
        <!-- for every item in posts, render this block -->
        {{#posts}}
        <li>
            <h4>{{title}}</h4>
            <p>{{body}}</p>
        </li>
        {{/posts}}
    </ul>
    {{/resources.blog}}
</body>
</html>

======

Resources

In order to pull remote data into a page, you need to define some resources. Resources are simply URLs to JSON documents, generally API responses, that are fetched and placed into the page context when it is loaded. For example:

I have a resource URL:

http://example.com/api/example.json

... and it returns this:

{
    "success": true
}

To include it in my page, I just add the url to the resources option in my page's configuration:

{{!
{
    ...
    "resources": {
        "example": "http://example.com/api/example.json"
    },
    ...
}
}}

And finally, in my page context I'll get:

{
    ...
    "resources": {
        "example": {
            "success": true
        }
    },
    ...
}

Dynamic Resources

Resources can also be requested dynamically by leveraging dynamic routes or querystrings. Just like dynamic routes, you use curly braces to denote dynamic parts of the resource URL. These dynamic parts will map to data from the route or querystring. Here's a quick example:

You have a page, /views/issues/{id}.hbs, and you specify your resource with this URL: https://api.github.com/repos/SparkartGroupInc/solidus/issues/{id}?details={details}.

Then say you visit the page like so: http://localhost:8080/issues/5?details=true.

Solidus will then request the resource with this URL: https://api.github.com/repos/SparkartGroupInc/solidus/issues/5?details=true.

======

Solidus is still under development. If you have comments or questions, please reach out to us in our IRC channel: #solidus on irc.freenode.net

======