Ingredients
Overview
Ingredients store the actual content of your site. They are stored as instances of Alchemy::Ingredient
subclasses on each Alchemy::Element
instance.
Alchemy uses Rails Single Table Inheritance to store the values in the same table.
Alchemy comes with a lot of predefined ingredients for the regular needs of a website project. Combine them like a chemestry kit into elements.
Ingredients are Rails models. It is pretty easy to add your own ingredient class as well.
Definition
Ingredients are defined as ingredients
on an element definition.
Global ingredient settings
When defining ingredients, you need to provide a role
and type
. You can set hints and default values as well.
# config/alchemy/elements.yml
- name: article
ingredients:
- role: headline
type: Text
hint: This is the headline
- role: color
type: Text
settings:
input_type: color
- role: copy
type: Richtext
default: Lorem ipsum dolor
as_element_title: true
role
String
requiredA lowercased unique (per element) role of the ingredient. Separate words needs to be underscored.
type
String
requiredAn type this ingredient is of. Alchemy has lots of built in ingredients for simple text, rich text, images, booleans and more.
hint
String|Symbol|Boolean
A hint for the user in the admin frontend that describes what the ingredient is used for. The hint is translatable if you provide an I18n translation
Symbol
instead of aString
. You may also set it totrue
to default to the I18n keyalchemy.ingredients_hints.your_ingredient_role
.default
String
The default text to prefill newly created elements. You may also use a symbol to set it to the I18n key
alchemy.default_ingredients_texts.your_ingredient_role
as_element_title
Boolean
For the displayed element title, the first ingredient is used. Use this setting to override this behaviour and show other ingredient as element title.
settings
Hash
A set of options to configure the ingredient. Each ingredient has its own set of options listed below.
Individual ingredient settings
Each ingredient type can have its own type of settings.
To configure these settings you have to pass them into its settings
key in the elements.yml
.
- name: my_element
ingredients:
- role: headline
type: Text
settings:
linkable: true
Text
Stores plain text of 255 chars max.
Use this for a headline, or a product name. The editor is renderd as a single lined input field. The view output will be sanitized and HTML escaped.
Settings
linkable
Boolean
If set to
true
, the user can add a link to the text.input_type
String
Change the input type of the form field displayed in the editor.
Example
- name: button
type: Text
settings:
linkable: true
Richtext
Used to store paragraphs of formatted text.
The editor is rendered as a textarea with embedded Tinymce Editor.
Settings
You can customize the Tinymce editor of a single element instance.
- tinymce
Hash
Example
- name: text
type: Richtext
settings:
tinymce:
style_formats:
- title: 'Subheadline'
block: 'h3'
INFO
See the Tinymce customization guide for all available options
Picture
Store references to pictures the editor assigns from the library.
The editor partial is rendered as a picture editor with a lot of options (i.e. image cropper).
The view partial renders the assigned picture, resizes it and crops it if needed.
INFO
See the rendering images guide for further information on the powerful image rendering engine of Alchemy.
Settings
size
String
The size the image should be downsized to. I.e. 400x300
crop
Boolean
(default: false)Crop the image to given size. This also enables the build in cropper tool.
srcset
Array<String>
A list of sizes of this image uses as sources list. Best used with the
sizes
setting for implementing responsive images.sizes
Array<String>
A list of screen sizes the image sources should be used for. Best used with the
srcset
setting for implementing responsive images.
Date
Use this to store a DateTime
value. Renders a datepicker in the editor partial.
The view output is passed through Rails' I18n Library, so it is fully localizable.
Settings
- date_format
String|Symbol
Either aString
with the format of Rubysstrftime
or aSymbol
of a date/time format defined in your locale files.
Html
Useful to store HTML code (i.e. a embed, or tracking code).
WARNING
The view renders the raw, not sanitized or escaped output. So be careful!
Boolean
Stores a Boolean
value in the database. Renders a checkbox in the editor partial.
Select
Renders a select box in the editor partial and stores the value as String
.
Useful for letting your user select from a limited set of choices.
Settings
select_values
Array
A list of values your users can select from. Use a two dimensional array for having value and text pairs.
Example
- name: width
type: Select
settings:
select_values: ['200', '300', '400']
TIP
If you need dynamic values (ie, a from a product catalogue), please create a custom ingredient class that provides the values.
Link
Stores a url in the database. Useful for linking things, where the editor should not set the linked text itself.
TIP
If you want the linked text to be editable by the editor use the Text with linkable: true
option instead.
Page
References an Alchemy::Page.
Renders a select box in the editor partial.
Useful for contact form follow up pages or other use cases where you want to reference another page.
Example
- name: contact_form
ingredients:
- role: follow_up_page
type: Page
Rendering ingredients within your element
Similar to rendering elements within layouts, ingredients are rendered on an element.
Page layouts use the <%= render_elements %>
helper to load an elements partial, elements use the <%= element_view_for %>
helper to expose a block that makes it easy to access the ingredients (instances of Alchemy::Ingredient
subclasses) of the element.
For example. With an article
element like this:
# config/alchemy/elements.yml
- name: article
ingredients:
- role: headline
type: Text
- role: color
type: Text
settings:
input_type: color
- role: copy
type: Richtext
The _article.html.erb
template generated by rails alchemy:elements --skip
would look like this:
<%- cache(article) do -%>
<%= element_view_for(article) do |el| -%>
<div class="headline">
<%= el.render :headline %>
</div>
<div class="color">
<%= el.render :color %>
</div>
<div class="copy">
<%= el.render :copy %>
</div>
<%- end -%>
<%- end -%>
Note how element_view_for
allows you to call el.render
on ingredients within the block.
TIP
element_view_for
wraps the block in a <div>
with a set ID and class by default, but this is customizeable if you pass in arguments:
<%= element_view_for(article, tag: :span, id: 'custom_id', class: 'custom_class') do |el| -%>
Without using the element_view_for
helper, you can still access ingredients:
article.ingredient_by_name('headline')&.value
But the el.render
helper takes care of generating the appropriate DOM elements to display the ingredient based on its type. It is recommended you rely on these helpers unless you are comfortable with the structure of the ingredient model you are trying to render.
Just like element_view_for
, you can pass options
and html_options
to el.render
:
<%= el.render :headline, options = {}, html_options = {} %>
You can check out the ElementViewHelper#render
helper for details.
NOTE
Options are not universally applied by all element types. For example, ElementRichText
ignores html_options
since it's already in HTML format and isn't wrapped in any special div. And you can't prevent the ElementPicture
from generating an <img>
tag.
Options
The options = {}
hash is used for formatting the child elements' tags. You can pass false
to not include tags inside the wrapper element. For more, see the source code here and here
Html_options
The html_option = {}
are:
:tag
- The HTML tag to be used for the wrapping element:id
- The wrapper tag's DOM ID.:class
- The wrapper tag's DOM class.