Skip to content

Pages ​

Pages in Alchemy do not hold content directly. Content is stored in ingredients inside elements that are placed on pages. A page defines which elements are available, how caching behaves, and where the page appears in the site's URL structure.

Pages are organized as a nested tree and have a unique URL slug. Each page has attributes for name, title, visibility, published status, and SEO metadata like meta description and meta keywords.

Every page has a page layout — a definition that controls which elements can be placed on it and how the page behaves.

Defining Page Layouts ​

Page layouts are defined in the config/alchemy/page_layouts.yml file. Each page layout needs at least a name.

Example ​

A contact page with a headline, a contact form, and a text element. The page should be unique (only one per language), and must not be cached because of form validation messages.

yaml
# config/alchemy/page_layouts.yml
- name: contact
  cache: false
  unique: true
  elements: [headline, contactform, text]
  autogenerate: [headline, contactform]

Page Layout Settings ​

name ​

String required

A lowercased unique name for the page layout. Separate words with underscores. This name is used to match the view partial in app/views/alchemy/page_layouts/ and is translatable for the admin interface.

elements ​

Array

A list of element names that can be placed on pages of this type. Elements are defined in config/alchemy/elements.yml.

yaml
- name: homepage
  elements: [hero, article, gallery]

autogenerate ​

Array

A list of element names that are created automatically when a new page of this type is created.

unique ​

Boolean (Default: false)

When true, this page layout can only be used once per language tree.

cache ​

Boolean (Default: true)

Set to false to disable cache headers for pages of this type. Recommended for pages with forms.

layoutpage ​

Boolean (Default: false)

Marks this as a global page — a page outside the normal page tree used for shared elements like headers and footers.

hide ​

Boolean (Default: false)

When true, this page layout is hidden from the "create new page" dialog.

searchresults ​

Boolean (Default: false)

When true, this page layout is used to render fulltext search results.

searchable ​

Boolean (Default: true)

When false, pages of this type are excluded from the built-in fulltext search.

editable_by ​

String|Array

Restrict which user roles can edit pages of this type.

fixed_attributes ​

Hash

Lock specific page attributes to fixed values that editors cannot change. The fixed values are enforced at save time and override any editor changes.

yaml
- name: readonly_page
  fixed_attributes:
    public_on: ~
    public_until: ~
    restricted: false

insert_elements_at ​

String

Set to top to insert new elements at the top of the page instead of the bottom (default).

hint ​

String|Boolean

A tooltip displayed to content editors when selecting this page layout. Set to true to use a translated hint from your locale files.

Page Templates ​

Each page layout has a view partial that is rendered inside the application layout (app/views/layouts/application.html.erb).

Page layout partials live in app/views/alchemy/page_layouts/ and are named after the page layout.

NOTE

If no partial is found for a page layout, the _standard.html.erb partial is rendered instead.

Template Generator ​

Alchemy provides a generator that creates page layout partials for all defined layouts.

bash
bin/rails g alchemy:page_layouts --skip

TIP

Pass --template-engine or -e to use haml, slim, or erb. The default follows your Rails application's template engine setting.

Rendering Elements ​

The generated partial contains a single call to render all elements on the page.

erb
<%= render_elements %>

Customize the HTML around this call to match your design. The render_elements helper accepts several options:

erb
<%# Render only specific elements %>
<%= render_elements only: "article" %>

<%# Render all except certain elements %>
<%= render_elements except: ["header", "footer"] %>

Global Pages ​

Global pages (or layout pages) live outside the normal page tree. They are never rendered on their own. Use them to store shared elements that appear on multiple pages — for example, a footer, header, or tracking codes.

To define a global page, set layoutpage: true in the page layout definition.

Rendering Elements from a Global Page ​

Use the from_page option of the render_elements helper. Pass an Alchemy::Page instance.

erb
<%# app/views/layouts/application.html.erb %>
<header>
  <%= render_elements only: "header",
        from_page: Alchemy::Page.find_by(page_layout: "header") %>
</header>

<main>
  <%= yield %>
</main>

<footer>
  <%= render_elements only: "footer",
        from_page: Alchemy::Page.find_by(page_layout: "footer") %>
</footer>

Publishing ​

Pages support time-based publishing with two timestamps:

  • public_on — the date and time the page becomes visible to visitors
  • public_until — the date and time the page is automatically unpublished

Editors can set these in the page settings dialog. When a page is published, Alchemy duplicates the draft version's elements into the public version. Visitors always see the public version.

TIP

Setting public_on to a future date schedules the page for publication. Setting public_until lets you create time-limited content like promotions or announcements.

Caching ​

Page caching is enabled by default. When active, page requests deliver Cache-Control headers that browsers, CDNs, and proxies use to cache the page. See the Configuration guide for global cache settings.

TIP

Set cache: false on individual page layouts to disable caching for pages with forms or personalized content.

Fragment Caching ​

Use Rails' fragment caching to cache page templates.

erb
<% cache @page do %>
  <%= render_elements %>
<% end %>

WARNING

Do not cache page templates that contain forms (contact forms, comment forms, etc.). Rails' CSRF protection token is inside the <form> tag and caching it will break form submissions.

SEO Metadata ​

Pages have title, meta_description, and meta_keywords attributes for SEO. Editors can set these in the page settings dialog.

NOTE

Starting with Alchemy 8.1, these attributes have moved to PageVersion. This means SEO metadata changes need to be published just like content changes. In Alchemy 8.0, they are still stored directly on the page.

URL Redirects ​

When a page's URL changes — because it was renamed or moved in the tree — Alchemy automatically creates a 301 redirect from the old URL to the new one. These redirects can be managed in the admin page settings.

Translating Page Layout Names ​

Page layout names are passed through Rails' I18n.

yaml
# config/locales/alchemy.de.yml
de:
  alchemy:
    page_layout_names:
      contact: Kontakt
      search: Suche

TIP

See the I18n guide for all available translation scopes.

BSD-3 Licensed · Hosting sponsored by netlify