Skip to content

Fractal: Prototyping & Styleguides

Bruno Meilick edited this page Aug 29, 2021 · 15 revisions

Brief

This document will show you how to setup Fractal to link your handlebars templates to your actual site content.

Overview

You need to install Fractal and point it to the the /site/templates-folder. You can use static json or yaml files to provide context data. To use the KQL Plugin to provide dynamic context data (your actual content!) via js promises you also add a user with special permissions, a little js helper and a few more node dependencies.

This example will use Yarn to install the dependencies but NPM will do just fine.

IMPORTANT: Since this project will use a /.env file it also assumes a public folder setup for you Kirby installation to keep that file save!

NOTE: This example assumes you use http://localhost.dev as your dev server in various places. Adjust it to your Valet, MAMP, XAMPP, Homestead etc.

Folder structure

  • /.env: host, user and pw for api auth
  • /fractal.js: fractal config
  • /package.json
  • /dist/ui/: export folder for styleguide
  • /public/index.php: your index.php in public folder setup
  • /public/ui: styleguide will be copied here post build
  • /site/templates/: your templates
  • /site/templates/_preview.hbs: fractals preview template
  • /site/templates/partials/: your partials
  • /site/ui-docs: folder for fractals styleguide docs (markdown files)

Install Fractal and Fractal CLI

yarn add @frctl/fractal --dev
yarn add global @frctl/fractal

Minimal Fractal config

/fractal.js

'use strict';

const fractal = module.exports = require('@frctl/fractal').create();

// /site/templates/_preview.hbs
fractal.components.set('default.preview', '@preview');

// templates and partials
fractal.components.set('path', __dirname + '/site/templates');

// docs
fractal.docs.set('path', __dirname + '/site/ui-docs');

// root
fractal.web.set('static.path', __dirname + '/public');

// styleguide export
fractal.web.set('builder.dest', __dirname + '/dist/ui');

Preview Template

Fractal can use a default template to render your templates into. This is useful to link to you own css and js files. Adjust this basic example to your needs.

/site/templates/_preview.hbs

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <link media="all" rel="stylesheet" href="{{ path '/assets/css/app.css' }}">
        <script src="{{ path '/assets/js/app.js' }}"></script>
        <title>Preview Layout</title>
    </head>
    <body>
    {{{ yield }}}
    </body>
</html>

Your templates and static context data

/site/templates/blog.hbs

<h1>{{ page.title }}</h1>
<nav>
  <ol>
    {{# page.posts }}
    <li><a href="{{ url }}">{{ title }}</li>
    {{/ page.posts }}
  </ol>
</nav>

/site/templates/blog.config.yml

status: ready
context:
  page:
    title: Blog
  posts:
    - title: A
      url: http://localhost/blog/a
    - title: B
      url: http://localhost/blog/b
    - title: C
      url: http://localhost/blog/c

Node scripts

Add these scripts to you package json.

package.json

{
"scripts": {
    "fractal-serve": "fractal start --sync",
    "fractal-build": "rm -rf ./public/ui; fractal build; mv ./dist/ui ./public/ui"
  },
}

You can now start prototyping with...

yarn fractal-serve

Or create the styleguide with...

yarn fractal-build

Dynamic Context Data

KQL Plugin

You need to install the KQL Plugin.

Allow basic auth and insecure connections to the Kirby API from localhost

/site/config/config.localhost.dev.php

<?php
return [
    'api' => [
        'basicAuth' => true,
        'allowInsecure' => true,
    ],
];

Create Role

/site/blueprints/users/api.yml

title: API
extends: users/default

permissions:
  access:
    panel: true
    users: false
    site: false
  site:
    update: false
  pages:
    create: false
    changeTemplate: false
    changeTitle: false
    changeURL: false
    hide: false
    sort: false
    update: false
    delete: false
  users:
    create: false
    createAvatar: false
    deleteAvatar: false
    changeName: false
    changeEmail: false
    changePassword: false
    changeRole: false
    delete: false
    update: false
  files:
    create: false
    changeName: false
    delete: false
    replace: false
    update: false

Create a User with Role API

This must be done using the Panel and use a secure password. This example uses the email [email protected] but you can pick any you like – it does not have to exist.

Create a .env file

/.env

KQL_BASEURL=http://localhost.dev/api
KQL_USER=[email protected]
KQL_PASSWORD=B9oF6E0Umjk24A22

NOTE: if you upload the /public/ui folder to your production server you also need to create a .env file on that server with matching KQL_BASEURL variable.

Install node dependecies

yarn add dotenv --dev
yarn add axios --dev

Add a JS helper to call the api

/site/templates/_kql.js

'use strict';

require('dotenv').config()
const axios = require('axios');

const instance = axios.create({
  baseURL: process.env.KQL_BASEURL,
  timeout: 5000,
  auth: {
    username: process.env.KQL_USER,
    password: process.env.KQL_PASSWORD
  },
  responseType: 'json',
});

const kqlQuery = async function (query) {
  let response = await instance.get('query', {
    data: query
  }).catch(error => console.log(error));
  return response.data.result;
};

exports.query = kqlQuery;

KQL query file for template

/site/templates/blog.json

{
  "query": "page",
  "select": {  
    "title": true,
    "posts": {
      "query": "page.children.listed.flip.limit(10)",
      "select": {
        "title": true,
        "url": true
      }
    }
  }
}

You can verify your setup with a tool like httpie.

http -a [email protected]:B9oF6E0Umjk24A22 POST localhost.dev/api/query < site/templates/blog.json

dynamic context data for fractal

/site/templates/blog.config.js

const kql = require('./_kql');

module.exports = {
  context: {
    page: kql.query(
       {
          ...require('./blog.json'),
          ...{ query: "page('blog')" }
       }
    )
  }
};

You can now start the fractal server with...

yarn fractal-serve