Class: Docco::Theme

Inherits:
Object
  • Object
show all
Defined in:
lib/docco/theme.rb

Overview

Theme is a templating system that uses ERB templates with named slots. It allows you to define a base template and then create specialized versions by filling in slots with different content.

Direct Known Subclasses

Docco::Themes::Default

Defined Under Namespace

Classes: Context, Slots, Static

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(tpl, slots: {}) ⇒ Theme

Initializes a new Theme instance.

Examples:

Create a theme with template and slots

tpl = ERB.new("<div><%= slots[:content] %></div>")
slots = { content: ERB.new("<p>Hello</p>") }
theme = Docco::Theme.new(tpl, slots: slots)

Parameters:

  • tpl (ERB)

    compiled ERB template

  • slots (Hash<Symbol, ERB>) (defaults to: {})

    hash of named slots with their ERB templates



70
71
72
73
# File 'lib/docco/theme.rb', line 70

def initialize(tpl, slots: {})
  @tpl = tpl
  @slots = slots
end

Class Method Details

.call(node) ⇒ Object

Raises:

  • (NotImplementedError)


56
57
58
# File 'lib/docco/theme.rb', line 56

def self.call(node)
  raise NotImplementedError, "define #{self}.call(node) to delegate .call(node) to the right root template (usually the homepage)"
end

.define(str) ⇒ Theme

Creates a new Theme from an ERB template string.

Template can also be a #read() => String interface for example a File or Pathname to read templates from disk

Examples:

Create a basic layout theme

Layout = Docco::Theme.define <<~HTML
  <html>
    <head>
      <title><%= slots[:doc_title] || 'Home' %></title>
    </head>
    <body>
      <%= slots[:main] %>
    </body>
  </html>
HTML
Page = Docco::Theme.define(Pathname.new('./theme/page.erb'))

Parameters:

  • str (String, #read)

    ERB template string that defines the layout

Returns:

  • (Theme)

    a new Theme instance with the compiled template



50
51
52
53
54
# File 'lib/docco/theme.rb', line 50

def self.define(str)
  str = str.read if str.respond_to?(:read)
  tmpl = ERB.new(str)
  new(tmpl)
end

Instance Method Details

#call(node) ⇒ String

Renders the theme with the given node by evaluating all slot templates and then the main template.

Examples:

Render a theme with a node

output = PageTemplate.call(node)
# => "<html><head>...</head><body>...</body></html>"

Parameters:

  • node (Object)

    the node object to render (available as ‘page’ in templates)

Returns:

  • (String)

    the rendered HTML output



125
126
127
128
129
130
131
132
# File 'lib/docco/theme.rb', line 125

def call(node)
  ctx = Context.new(node:, slots: {})
  slots = @slots.transform_values do |tpl|
    tpl.result(ctx.get_binding)
  end
  ctx = Context.new(node:, slots:)
  @tpl.result(ctx.get_binding)
end

#define(str = nil) {|Slots| ... } ⇒ Theme

Creates a new theme by defining slots for the template. Can accept either a string (which becomes the :main slot) or a block that yields a Slots object for defining multiple slots.

Examples:

Define a theme with a string for the main slot

HomeTemplate = Layout.define <<~HTML
  <h1>Home page</h1>
  <% page.sections.each do |s| %>
    <%= s.title_html %>
  <% end %>
HTML

Define a theme with multiple slots using a block

PageTemplate = Layout.define do |tpl|
  tpl.slot :doc_title, '<%= page.title %>'
  tpl.slot :main, <<~HTML
    <h1><%= page.title %></h1>
    <% page.nodes.each do |n| %>
      <%= n.to_html %>
    <% end %>
  HTML
end

Parameters:

  • str (String, nil) (defaults to: nil)

    optional string to use as the :main slot

Yields:

  • (Slots)

    yields a Slots object for defining named slots

Returns:

  • (Theme)

    a new Theme instance with the defined slots



101
102
103
104
105
106
107
108
109
# File 'lib/docco/theme.rb', line 101

def define(str = nil, &)
  slots = Slots.new
  if str
    slots.slot(:main, str)
  elsif block_given?
    yield slots
  end
  self.class.new(@tpl, slots: slots.to_h)
end