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.
# 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.
- 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.
- name: readonly_page
fixed_attributes:
public_on: ~
public_until: ~
restricted: falseinsert_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.
bin/rails g alchemy:page_layouts --skipTIP
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.
<%= render_elements %>Customize the HTML around this call to match your design. The render_elements helper accepts several options:
<%# 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.
<%# 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 visitorspublic_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.
<% 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.
# config/locales/alchemy.de.yml
de:
alchemy:
page_layout_names:
contact: Kontakt
search: SucheTIP
See the I18n guide for all available translation scopes.