Skip to content

Latest commit

 

History

History
499 lines (325 loc) · 10.4 KB

ViewAPI.md

File metadata and controls

499 lines (325 loc) · 10.4 KB

Setup

Engine

Template engine can be set globally, at class level, then inside actions you simply call render and counterparts.

This way you can change your engine for an entire app with minimal impact, without refactoring a single action.

By default Espresso uses ERB template engine.

Example: - Set :Erubis for current controller

class App < E
    # ...
    engine :Erubis
end

Example: - Set :Haml for an entire slice

module App
    class News < E
        # ...
    end

    class Articles < E
        # ...
    end
end

app = App.mount do
    engine :Haml
end
app.run

If engine requires some arguments/options, simple pass them as consequent params.

Just like

engine :SomeEngine, :some_arg, :some => :option

Example: - Set default encoding

engine :Erubis, default_encoding: Encoding.default_external

[ contents ↑ ]

Extension

Espresso will use the default extension of current engine.

To set a custom extension, use engine_ext.

Example:

class App < E
    # ...

    engine :Erubis
    engine_ext :xhtml
end

[ contents ↑ ]

Templates path

By default, Espresso will look for templates in "view/" folder, inside your app root.

If that's not your case, use view_path to inform Espresso about correct path.

Example:

class App < E
    map '/cms'

    view_path 'base/view'

    def index
        # ...
        render # this will render base/view/cms/index.erb
    end

    def books__free
        # ...
        render # this will render base/view/cms/books/free.erb
    end
end

For cases when your templates are placed out of app root, provide an absolute path to templates, i.e., a path starting with a slash.

Example:

class News < E

    view_path File.expand_path '../../../shared-templates', __FILE__
    # ...
end

If app deployed on a non-Unix-like system, you should use view_fullpath instead.

Example:

class News < E

    view_fullpath File.expand_path '../../../shared-templates', __FILE__
    # ...
end

[ contents ↑ ]

Layouts path

By default, Espresso will look for layouts in same folder as templates, i.e., in "view/"

Use layouts_path to set a custom path to layouts.
The path should be relative to templates path.

Example: - Search layouts in "view/layouts/"

class App < Ruby
    # ...
    layouts_path 'layouts/'
end

[ contents ↑ ]

Layout

By default no layouts will be searched/rendered.

You can instruct Espresso to render a layout by using layout

Example: - All actions will use :master layout

class App < Ruby
    # ...
    layout :master
end

Example: - Only :signin and :signup actions will use :member layout

class App < Ruby
    # ...
    setup :signin, :signup do
        layout :member
    end
end

To make some action ignore layout rendering, use layout false

Example: - All actions, but :rss, will use layout

class App < Ruby
    # ...
    layout :master
    setup :rss do
        layout false
    end
end

[ contents ↑ ]

Render

Rendering Templates

To render the template of current action, simply call render or render_partial without arguments.

class App < E
  
  map 'news'
  view_path 'base/views'
  layout :master
  engine :Haml

  def some_action
      # ...
      render  # will render base/views/news/some_action.haml, using :master layout
  end

  def some__another_action
      # ...
      render_partial  # will render base/views/news/some__another_action.haml, without layout
  end

end

=== Important === Template name should exactly match the name of current action, including REST verb, if any.

def get_latest
  render # will try to render base/views/news/get_latest.haml
end

def post_latest
  render # will try to render base/views/news/post_latest.haml
end

Also, if current action called with a specific format, template name should contain it.

class App < E
  
  map '/'
  format :xml, :html

  def post_latest
    render  # on /latest      it will render view/post_latest.erb
            # on /latest.xml  it will render view/post_latest.xml.erb
            # on /latest.html it will render view/post_latest.html.erb
  end
end

To render a template by name, pass it as first argument.

render :some__another_action      # will render base/views/news/some__another_action.haml

render_partial 'some_action.xml'  # will render base/views/news/some_action.xml.haml

render 'some-template'            # will render base/views/news/some-template.haml

render_p 'some-template.html'     # will render base/views/news/some-template.html.haml

To render a template located higher than your current action, use ../:

class App < E
  map :pages

  view_path 'templates'
  
  def some_meth
    render                   # will render templates/pages/some_meth
    render '../some-file'    # will render templates/some-file
  end
end

To render a template of inner controller, pass controller as first argument and the template as second.

class Articles < E
  
  view_path 'templates'
  engine :Slim
  # ...
end

render Articles, :most_popular         # will render templates/articles/most_popular.slim
render Articles, 'some-template.xml'   # will render templates/articles/some-template.xml.slim

Scope and Locals can be passed as consequent arguments, orderlessly.
The scope is defaulted to the current controller and locals to an empty Hash.

As extension will be used the explicitly defined extension(at class level) or the default extension of used engine.

Layout

  • If current action rendered, layout of current action will be used, if any.
  • If custom action rendered, layout of given action will be used, if any.
  • If an arbitrary template rendered, layout of current action will be used, if any.

Engine

As engine will be used the effective engine for current context.
Meant engine defined for current or given action, or engine defined for all actions, or default engine - ERB.

Inline rendering

If block given, the template will not be searched/rendered.
Instead, the string returned by the block will be rendered.
This way you'll can render data from DB directly, without saving it to file system.

=== Important === If custom controller given, rendering methods will use the path, engine and layout set by given controller.

[ contents ↑ ]

Rendering Layouts

render_layout will render the layout of current(or given) action or an arbitrary layout file.

Render the layout of current action

render_layout { 'some string' }

Render the layout of current action within custom scope

render_layout Object.new do
    'some string'
end

Render the layout of current action within custom scope and locals

render_layout Object.new, :some_var => "some val" do
    'some string'
end

Render the layout of :news action

render_layout :news do
    'some string'
end

Render the .html layout of :news action

render_layout 'news.html' do
    'some string'
end

Render layout of :latest action of News controller

render_layout News, :latest do
    'some string'
end

Render an arbitrary file as layout

render_layout 'layouts/master' do
    'some string'
end

[ contents ↑ ]

Ad hoc rendering

Any of render, render_partial and render_layout methods has ad hoc counterparts, like render_haml, render_erb_partial, render_liquid_layout and so on.

Works exactly as common rendering methods except they are using a custom engine and extension.

Used when you need to "quickly" render a template, without any previous class-level setups.

render_haml        # will render the template and layout of current action using Haml engine

render_haml_p      # will render only the template of current action using Haml engine

render_haml_l      # will render only the layout of current action using Haml engine

[ contents ↑ ]

Templates Compilation

For most web sites, most time are spent at templates rendering.
When rendering templates, most time are spent at files reading and templates compilation.

You can skip these expensive operations by using built-in compiler.

It will simply store compiled templates in memory and on consequent requests will just render them, avoiding filesystem calls for reading and CPU time for compiling templates.

To use compiler you should simply pass a key/value pair to locals.
The key should be an empty string and the value an unique ID or simply true.

Example:

render '' => true

render_partial :some_action, '' => true

render_partial :some_action, '' => :some_action, :foo => :bar

render_file 'some/file', Object.new, '' => true

render_haml "path/to/file", '' => "path/to/file"

To clear compiled templates call clear_compiler!.
If called without arguments, it will clear all templates.
To clear only some templates, pass their unique IDs as arguments.

Example:

class App < E

    def index
        @banners = render_view :banners, '' => :banners
        @ads = render_view :ads, '' => :ads
        render '' => true
    end

    before do
        if 'some condition occurred'
            # updating only @banners and @ads
            clear_compiler! :banners, :ads
        end
        if 'some another condition occurred'
            # clear all templates
            clear_compiler!
        end
    end
end

By using clear_compiler_like! you can clear only keys that match a given regexp or even array.

def index
    @procedures = render :procedures,      '' => [user, :procedures]
    @actions    = render :actions,         '' => [user, :actions]
    @banners    = render_partial :banners, '' => :user_banners
    render
end

private
def clear_compiled_templates

    # clearing [user, :procedures] and [user, :actions]
    clear_compiler_like! [user]

    # clearing any templates starting with 'user'
    clear_compiler_like! /\Auser_/

end

[ contents ↑ ]