Key Concepts: Template Development - blacklight-cms/blacklight-core GitHub Wiki

Modules

The code is segmented into separate modules each of which is a separate GIT repo. These repos are cloned automatically via the bl module install cli command.

File System

Modules are namespaced by site. They are installed under the blacklight_modules directory. For example, the fshr.shared module is part of the fshr site and the repo is located at fs-blacklight/blacklight_modules/fshr/shared. Likewise, the fshr.magazine module can be found at fs-blacklight/blacklight_modules/fshr/magazine.

Each module will have the following 3 directories:

  • components : code to process data and the templates to render that data
  • apps : module specific routes and helper functions
  • public : assets to be served to the browser (JS, CSS, images)

These key directories for all of the modules are aggregated via symlinks to common directories at the fs-blacklight level.

  • fs-blacklight/components
  • fs-blacklight/apps
  • fs-blacklight/public

As these are just symlinks, editing files through them may cause some confusion. It's best to edit the files directly under the blacklight_modules/. Being aware of the symlinks is imperative, though, as they're used by the framework to resolve public asset request and model processing / template rendering. If for some reasons the symlinks are broken they can be established with the following command

bl module relink

Example for fshr.magazine module:

  • fs-blacklight/blacklight_modules/fshr/magazine/components -> fs-blacklight/components/fshr/magazine
  • fs-blacklight/blacklight_modules/fshr/magazine/apps -> fs-blacklight/apps/fshr/magazine
  • fs-blacklight/blacklight_modules/fshr/magazine/public -> fs-blacklight/public /fshr/magazine

Template Resolution

The Handlebar template used is determined by the sling:resourceType. Resource types are '/' delimited Strings, and are determined in a number of ways as detailed in the component Handlebar helper . Blacklight resolves the resource by checking for it under fs-blacklight/components/, specifically fs-blacklight/components//.hbs. If no template is found, the data will be rendered in the default tabular data view.

Example:

  1. resource type of fshr/magazine/pages/article is received
  2. Blacklight looks for fs-blacklight/components/fshr/magazine/pages/article/article.hbs

Asset Resolution

Similarly to how resource types are resolved, Blacklight looks for the requested asset under fs-blacklight/public. However, assets must be predicated with '/alt/' which indicates that a public asset is being requested. The '/alt/' is ignored when resolving the asset path. If is revision number is in the request that will be ignored as well.

Example:

  1. Asset request for '/alt/fshr/shared/caw/caw.js'
  2. Blacklight looks for fs-blacklight/public/fshr/shared/caw/caw.js

Task Runners

Blacklight is setup to use a Task Runner to compile JS / CSS if desired. This can be accomplished by adding a few entries to the module's package.json.

{
	"scripts": {
	    "asset-build": "", // commands to build / compile assets
	    "asset-watch": "", // commands to setup watcher for automatic recompilation
	    "asset-install": "" // commands to install dependencies for task runner execution
	}
}

Example scenario - we want to add a Task Runner to the fshr.magazine module :

1. Create directory to store tasks and pre-compiled code

Best practice is to put the Task Runner items in a subdirectory rather than in the root of the module. This allows for a separate package.json that can deal specifically with the Task Runner needs.

cd fs-blacklight/blacklight_modules/fshr/magazine
mkdir asset-build
cd asset-build
2. Create a package.json
vim package.json

Copy the following content.

{
	"name": "FS Magazine Asset Builder",
	"version": "1.0.0",
	"description": "FS Magazine Asset Builder",
	"main": "gruntfile.js",
	"dependencies": {
		"grunt": "^0.4.5",
		"grunt-contrib-jshint": "~0.8.0",
		"grunt-contrib-watch": "~0.5.3"
	}
}
3. Create a Gruntfile.js
vim Gruntfile.js

Copy the following content.

module.exports = function(grunt) {

  grunt.initConfig({
    jshint: {
      files: ['Gruntfile.js', '../public/**/*.js'],
      options: {
        globals: {
          jQuery: true
        }
      }
    },
    watch: {
      files: ['<%= jshint.files %>'],
      tasks: ['jshint']
    }
  });

  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.registerTask('default', ['jshint']);
};
4. Modify the module package.json to automatically invoke the Grunt tasks.
cd ..
vim package.json
{
	"scripts": {
	    "asset-build": "cd asset-build; gulp",
	    "asset-watch": "cd asset-build; gulp watch", 
	    "asset-install": "cd asset-build && npm install" 
	}
}

Viewing Template Data

The data that is passed to the top level Handlebar template can be seen directly in the browser by altering the extension used. Ex: viewing the page /content/my-site/en/properties/minneapolis/things-to-do on local environment