Class: Noumenon::Template

Inherits:
Object
  • Object
show all
Defined in:
lib/noumenon/template.rb

Overview

Templates specify the structure and presentation of a particular piece of content in a Noumenon site, and are usually provided by a theme.

A template is split into two parts, the metadata, which defines what data is needed for the template, and a Liquid template, which defines how the data should be presented. When loaded from a file, a template will look like this:

title:
  label: Page title
  required: true
  type: string
  help: The title displayed at the top of the page
author:
  label: Author
  required: false
  type: string
  help: The author of the article. If not provided, no byline will be shown.
body:
  label: Body text
  required: true
  type: text
  help: The main article body. Will be processed with Textile for formatting.
---
<h1>{{ title }}</h1>
{% if author %}
  <p class="byline">By {{ author }}</p>
{% endif %}
{{ body | textilize }}

And can be rendered like this:

Template.from_file("/path/to/template").render("title" => "An Example Page", "author" => "Jon Wood", "body" => "This is an article...")

If any required fields are missing from the data provided then a MissingContentError will be raised.

Defined Under Namespace

Modules: CoreTags Classes: MissingContentError, NotFoundError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source = nil, content = nil, fields = {}) ⇒ Template

Creates a new Template instance.

Examples:

Loading a template from a database

fields = load_field_rows.inject({}) do |fields, row|
  fields[row[:name]] = { "required" => row[:required], "type" => row[:type] }
end

Noumenon::Template.new("mysql://localhost/database/table#row_32", row[:content], fields)

Parameters:

  • source (#to_s) (defaults to: nil)

    the location the template was loaded from

  • content (#to_s) (defaults to: nil)

    the Liquid template to render

  • fields (Hash, #each) (defaults to: {})

    the list of fields used within the template



113
114
115
116
117
# File 'lib/noumenon/template.rb', line 113

def initialize(source = nil, content = nil, fields = {})
  @source = source
  @content = content
  @fields = fields
end

Instance Attribute Details

#contentObject

The template view.



59
60
61
# File 'lib/noumenon/template.rb', line 59

def content
  @content
end

#fieldsObject

The fields used by this template.



63
64
65
# File 'lib/noumenon/template.rb', line 63

def fields
  @fields
end

#sourceObject

The location this template was loaded from.



55
56
57
# File 'lib/noumenon/template.rb', line 55

def source
  @source
end

Class Method Details

.dropsObject



89
90
91
# File 'lib/noumenon/template.rb', line 89

def self.drops
  @drops ||= {}
end

.from_file(path) ⇒ Noumenon::Template

Loads a template from the specified path.

Parameters:

  • path (String, #to_s)

    the file to load the template from

Returns:

Raises:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/noumenon/template.rb', line 73

def self.from_file(path)
  raise NotFoundError.new("No template could be found at #{path}.") unless File.exists?(path)
  
  content = File.read(path)

  parts = content.split("\n---\n")
  if parts.size == 1
    fields = {}
  else
    fields = YAML.load(parts.first)
    content = parts.last
  end

  self.new(path, content, fields)
end

.register_drop(name, klass) ⇒ Object



93
94
95
# File 'lib/noumenon/template.rb', line 93

def self.register_drop(name, klass)
  drops[name] = klass
end

Instance Method Details

#render(page_content = {}) ⇒ #to_s

Renders the template.

Parameters:

  • page_content (Hash, #each) (defaults to: {})

    the content to provide to the template

Returns:

  • (#to_s)

    the rendered template

Raises:



125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/noumenon/template.rb', line 125

def render(page_content = {})
  fields_from_page = page_content.stringify_keys
  
  missing_fields = []
  fields.each do |key, field|
    missing_fields << key if field["required"] && !fields_from_page.key?(key)
  end

  raise MissingContentError.new("The following fields were missing from your content: #{missing_fields.sort.join(", ")}") unless missing_fields.empty?
  
  Liquid::Template.parse(content).render(fields_from_page.merge(self.class.drops))
end