Using wf-directives
Intro
wf-directives are HTML attributes whose names start with wf-
that allow you to control the behaviour of the editor.
A wf-directive can (optionally) have a value. For example wf-new
doesn't need any value, but one can be passed wf-new="2"
if two instances of this module should be added in a new article/board.
Some wf-directives accept an argument. For example wf-filter:avatar="currentPage.authors?.[0]?.avatar"
- in this case the Imagine filter's name (avatar
) is being passed as an argument.
Some wf-directives accept one or more modifiers, boolean flags that change the default behaviour of the wf-directive. For example wf-filter.absolute.no-alt="image_800_600"
displays the image's thumbnail absolute URL with the image_800_600
Imagine filter, without adding the alt
attribute to the bound element.
wf-allow
Must be used on a wf-module
element.
Marks whether the editor can add multiple instances of this module or whether the instances of this module can be deleted. Use +
to allow adding, -
to allow deleting.
Thus:
wf-allow=""
don't allow neither adding, nor deleting. For example: the article templates must have one title and only one title.wf-allow="-"
allow deleting, but not adding. For example: the main image composite module may be deleted to free up editor space. When deleted, XalokNext displays a button to add it back. When added back, no two instances are allowed (only one main image per article)wf-allow="+"
allow adding, but not deleting. Make some noise if you find an usage for this scenario 😃wf-allow="+-"
allow both adding and deleting. Useful for modules inside the body of the article (e.g. paragraphs)
wf-article-types
Must be used on a wf-module="composite"
element that allows embedding page
content models. It limits the search results to display only articles with the given templates.
Example: Allow including only articles with the gallery
or video
template:
<div wf-role="article"
wf-article-types="gallery,video"
>
[[ page.title ]]
</div>
wf-class
This is an element wf-directive, that is, it's not an attribute, but a HTML element. Displays a radio setting for the module and binds its value to the class
attribute of the element containing it.
Note: This works with any element inside the module, not just with the module element.
Example: Adds the red
or blue
CSS class to the <a>
element:
<div wf-role="page">
<a wf-href>
<wf-class name="link-color">
<title>Choose a color for the link</title>
<option value="">No color</option>
<option value="red">Red</option>
<option value="blue">Blue</option>
</wf-class>
[[ page.title ]]
</a>
</div>
Also, it selects by default the first option with value=""
. To select automatically an option with value not empty, it's needed to add that class in the element too:
<div wf-role="page">
<a wf-href class="red">
<wf-class name="link-color">
<title>Choose a color for the link</title>
<option value="red">Red</option>
<option value="blue">Blue</option>
</wf-class>
[[ page.title ]]
</a>
</div>
wf-cm-text
Used on a text submodule of a composite that allows content models, upon selecting a content model it fills the contents of the text submodule with the given content model's property.
Example: Automatically fill the contents of the image_description
text submodule with the image.description
property:
<div wf-role="image">
<span wf-role="image_description"
wf-cm-text="image.description"
></span>
</div>
This wf-directive can also be used with a template filter, that allows processing the bound value before displaying it.
Example: Automatically fill the contents of the author
module with the names of the authors, separated by comma - it uses the authorNames template filter:
<span
wf-role="authors"
wf-cm-text="filters.authorNames(currentPage.authors)"
></span>
Note: For a short while between v7.2- v7.3.0-beta.3 one needed to use templateFilters
. This has been changed for consistency with how filters are used inside modules.
Example: Showing the evaluation scope of a filter inside wf-cm-text
:
<div
wf-role="main_image">
<span
wf-role="description"
wf-cm-text="filters.someFilter(image.title, module)"
:data-attr="module.content"
>
</span>
</div>
In the example above the module
that is sent to someFilter
is referring to the data of the main_image
module - that's the module that holds the image
as well, while module
that is used for :data-attr
binding is main_image.description
.
Note: If a wf-cm-text
uses a template filter you can use all the variables that are available in the parent module - including store
and wfRolePath
. This should give you the flexibility to (e.g.) combine multiple content models inside a filter, or access data from other modules too.
Modifiers:
fresh
: In the example above, once an image is selected, its description will be copied into theimage_description
submodule's content. This will remain unchanged, even if the original image's description is changed afterwards. The default mode is useful for keeping the visual appearance, no matter of the subsequent changes to the original content model - for example the article title in a board will remain the same length, no matter if the original article's title has been edited and made much longer. There are cases, though, where the changes made to the content model can be refreshed when rerendering the article/board - for example the name of an article's author.Example: Reflect changes to the author's name, unless the
author_name
module has been manually edited inside the article/board:html<span wf-role="author_name" wf-cm-text.fresh="currentPage.authors?.[0]?.name" ></span>
wf-collapse-switch
Used in conjunction with wf-group. When a module belongs to a group, the list of modules in that group is displayed as separate buttons, if space allows it (e.g.: if the toolbar is horizontal and the list of the modules is small enough and fits the toolbar). If the list is too long, a "more" button is shown, when clicked, it shows a popover with the remaining list. wf-collapse-switch
forces displaying the "more" button, no matter if there is enough space or not.
This is useful when one wants to add thumbnails for the modules - it can be more easily done in the popover, where there's much space, rather than on the small toolbar buttons.
wf-collection-item
Used to allow selecting multiple content models, duplicating the bound module for each selected content.
Example: Allow selecting multiple page
content models in the related_articles
module, creating a related_article
sumodule for each page
that was selected.
<div wf-role="related_articles">
<div wf-role="related_article"
wf-collection-item
>
<a wf-href>[[ page.title ]]</a>
</div>
</div>
wf-current-time
Used on a text module, it fills its contents with the current time whenever a new instance of the bound module is added.
Example:
<span wf-role="current_time"
wf-current-time
></span>
Value (default HH:mm
): This wf-directive accepts a value to specify the format of the time: wf-current-time="HH:mm:ss"
wf-current-uri
Highlights the active item in a menu.
NOTE!!! This must be used in conjunction with wf-menu-item
, see examples below.
NOTE!!!: This wf-directive works ONLY if the board is rendered through wf_cms_render_menu_board
!!!
{{ wf_cms_render_<b>menu_</b>board('main-menu', {
template: 'board/menu/main',
title: 'board-title.category-main-menu'|trans,
<b>entity: category</b>, // or `user`, or `tag`
}) }}
You can reuse this board on other pages too, to use the same menu. Note that in this case you MUST pass the currentUri
option, the example below assumes this menu board is included on the homepage:
{{ wf_cms_render_menu_board('main-menu', {
template: 'board/menu/main',
title: 'board-title.home-main-menu'|trans,
<b>currentUri: path('wf_homepage'),
strictMatch: true</b>
}) }}
NOTE: See the strictMatch
option passed above. When the menu is displayed on a category page, it's likely that on the "Sports/Football" category highlights the "Sports" menu option. This is done by matching the "Sports" slug against the "Sports/Football" slug (/sports
starts with /sports/football
). But on the homepage, this behaviour would match all the options of the menu, since everything is "under" the /
URL.
For cases when none of the menu items needs to be highlighted (e.g.: static pages that are not linked in the main menu), you can pass currentUri
as false
:
{{ wf_cms_render_menu_board('main-menu', {
template: 'board/menu/main',
title: 'board-title.home-main-menu'|trans,
<b>currentUri: false</b>
}) }}
You can use this directive either on the wf-menu-item
element:
<ul class="main-menu">
<li wf-module="composite"
wf-role="item"
wf-new
wf-toolbar-position="bottom"
wf-allow="+-"
><a
wf-module="body_text"
wf-role="link"
wf-new
wf-toolbar-position="none"
wf-allow=""
wf-menu-item
wf-current-uri-class="active"
>{{ 'main-menu.item'|trans }}</a>
</li>
</ul>
or on one of its parents:
<ul class="main-menu">
<li wf-module="composite"
wf-role="item"
wf-new
wf-toolbar-position="bottom"
wf-allow="+-"
wf-current-uri-class="active"
><a
wf-module="body_text"
wf-role="link"
wf-new
wf-toolbar-position="none"
wf-allow=""
wf-menu-item
>{{ 'main-menu.item'|trans }}</a>
</li>
</ul>
wf-croppable
Used on images. Value (optional, default: true
):
Example: Disable the crop for an image
<img
wf-croppable="false"
wf-filter="image_44_44"
/>
wf-debug
This is a virtual wf-directive, it's being added automatically to all wf-module
elements. Its role is to add in development a debug icon to the toolbar that, when clicked, logs to the browser's console the context of a module - all the variables that can be used inside that module.
Check the Disabling the debug module toolbar button section for details on how to disable this in production.
wf-embed-types
Used only in wf-module="embed"
modules. This allows to specify which custom module is the embed module be allowed to edit.
Example: Allow to use only the HTML custom-module.
<div wf-role="html"
wf-module="embed"
wf-embed-types="html"
></div>
Example: For multiple modules, use commas.
<div wf-role="social"
wf-module="embed"
wf-embed-types="twitter, instagram, youtube"
></div>
Example: For custom modules with more than one word, use "-" instead of spaces.
<div wf-role="elections"
wf-module="embed"
wf-embed-types="buscador-de-elecciones"
></div>
wf-facet
Used only in wf-module="embed"
modules. Embed modules allow defining a different HTML for desktop, amp, etc. By default, it uses the desktop
HTML to render the contents, using a different HTML can be controlled with this wf-directive.
Example: Render the embed module using the amp HTML:
<div wf-role="embed"
wf-facet="amp"
></div>
wf-filter
Used to bind
- the
src
orsrcset
attributes to the image's thumbnail URL - the
alt
attribute to the image's description - the
width
/height
attributes to the thumbnail's size - to prevent CumulativeLayoutShift - this works only when the resulting image's size is known without actually resizing the image - that is, only formode: outbound
Imagine filters.
Example: bind the src
attribute to the thumbnail URL corresponding to the image_600_480
Imagine filter.
<div wf-role="image">
<img wf-filter="image_600_480" />
</div>
Example: If bound to a <source>
element, it binds the srcset
attribute instead of the src
:
<div wf-role="image">
<picture>
<source wf-filter.no-alt="image_600_400" media="(min-width: 600px)" />
<source wf-filter.no-alt="image_480_300" media="(min-width: 480px)" />
<img wf-filter="image_800_600" />
</picture>
</div>
Value: Either the name of the Imagine filter to be used, when it needs to bind the image
content model, or the content model to be used.
Example: Bind the src attribute to the thumbnail URL corresponding to the avatar
Imagine filter for the article's author avatar:
<img wf-filter:avatar="currentPage.authors?.[0]?.avatar" />
Note: If the projects adds a custom image to an entity, e.g.: a logo
to a category, read the augment content models section.
Argument: Specify the Imagine filter to be used. Used only if binding an image coming not from a content model, but from a different source, e.g. the author's avatar. Check the example above for this usage.
Modifiers:
no-alt
: don't bind thealt
attribute. In<picture>
elements, thealt
attribute is needed only for the<img>
, not for each<source>
no-size
: don't bind thewidth
/height
attributes.absolute
: bind the absolute URL of the thumbnail - by default it binds the relative URL.- v7.2
full-src
: adddata-full-src
to this element. This attribute is used internally by the focal point editor, and it shouldn't be needed on public facing pages. It can be optionally enabled on server side rendered pages by using this modifier.
wf-formattings
Used on a body_text
module. Controls what options are displayed to format the text.
Example: displays bold, italic and underline buttons:
<p wf-formattings="b,i,u"></p>
Available formattings:
b
: boldu
: underlinei
: italicol
: ordered listul
: unordered lista
: links
: strikethrough
There are also some shorthands available:
short
: bold, underline, italic, strikethrough, linklists
: ordered and unordered listsextended
: includesshort
+lists
You can combine these options in any way you want:
<p wf-formattings="b,i,lists"></p>
wf-group
Used on a module. Putting multiple modules in the same wf-group
, XalokNext displays buttons on the toolbar of either of these modules that allows switching to any other module in the group.
Example: Allows switching between different headings:
<h2 wf-role="h2"
wf-group="headings"
></h2>
<h3 wf-role="h3"
wf-group="headings"
></h3>
Note: All the modules that are part of the same group must be added in the same container element.
wf-href
Allows linking to a content model.
Example: Link to the page
content model:
<div wf-role="article">
<a wf-href>[[ page.title ]]</a>
</div>
Value (optional, default page
): the content model to link to.
Example: Link to the page
's category:
<div wf-role="article">
<a wf-href="page.category">[[ page.category?.title ]]</a>
</div>
Modifiers:
absolute
: generate the absolute URL.
v7.1+ wf-link-content-model
Used on a module element.
This directive allows for the selection of specific entity fields from other models. Currently, when any content model, such as an image, is associated with another content model, like a category, they are linked without regard for order. This means that if a module contains multiple content types, the image associated with any content type could potentially overwrite another. Additionally, if a content model, such as a category, has multiple content model fields, such as multiple image fields, all of them are linked in any order, potentially overriding each other. This directive enables the specification of which content model, such as an image, from what content model, such as a category, should be linked.
The format of this directive is as follows:
format = {linkage} [ , {linkage} ]*
linkage = {targetContentType} : {sourceContentType} . {field}
Here, {linkage} represents a single linkage specification, and it can be followed by zero or more additional linkages separated by commas. Each linkage consists of three parts separated by colons and periods.
- {targetContentType} specifies the content type where the linked field will reside (e.g.
image
). - {sourceContentType} specifies the content type from which the field will be linked (e.g.
category
). - {field} denotes the specific field within the source content type that will be linked (e.g.
iTunesImage
).
This format allows for precise specification of the relationships between different content types and the field to be used.
Example in context:
<div
wf-role="emision"
wf-new
wf-allow="+-"
wf-toolbar-position="top"
wf-link-content-model="image:category.mainimage"
>
<div>
<img wf-filter="image_32_32" width="32" height="32" />
</div>
<div
wf-role="subemision"
wf-allow="+-"
wf-toolbar-position="left"
wf-link-content-model="image:category.itunesimage"
>
<div>
<img wf-filter="image_32_32" width="32" height="32" />
</div>
</div>
</div>
In the previous example, the emision
will take the mainimage
field from the categories as the image (which can also be manually replaced by the editor). Conversely, although the categories have multiple fields of type image, the subemision
will take (attention, from another linked category, not from the emission category) and allow manual modification of the image from the itunesimage
field.
In the event that the image is not intended to be modified by the editor, this directive should not be used. Instead, simply indicate where to retrieve the image. For example:
<img wf-filter:image_32_32="category?.mainimage" width="32" height="32" />
wf-max
All the modules. Allow to limit the number of modules added, when the number wf-max is reached, the button for add new module disappear
Example: Limit the modules allowed to be added to 3
<div wf-role="article"
wf-allow="+-"
wf-max="3"></div>
wf-maxlength
Used in a text module. Puts a hard limit on the length of text that is allowed to be entered. This acts very similarly to wf-softmaxlegnth, when the limit is reached, the module gets a red(dish) background but the editor is still allowed to enter more characters. The difference comes when the user tries to save, when the text put in is lengthier than the configured size: with wf-softmaxlength
they are allowed, with wf-maxlength
they get an error.
Unlike forcing a trimming of the content to the configured size and not allowing any extra characters, this approach benefits the editors, especially when it comes to pasting text that is longer than the configured size. Or, in the case of board modules, importing an article (for example) that has the title longer than the configured size.
In these case, possible approaches for forcing the exact size and not allowing more characters would be:
- trimming the incoming text (pasted or inherited from the content model) to the configured size. This would have the disatvantage that the editor cannot see what was trimmed. In the case of paste, they'd be forced to use an external tool (e.g. a text processor) to get the length of the pasted text right before pasting it into XalokNext. In the case of trimming (for example) the title of an article, they'd have to open a new tab to get the actual title and then use the external tool.
- allowing incoming text longer than the configured size, but not allowing adding any extra characters: it's very likely that the editor wants to shorten the text by changing some words/expressions to shorter variants. Blocking any extra characters from being input would mean they'd have to do this in one go: changing an entire expression at once to make the text shorter than the configured size. But it's likely that they'd need to do this for multiple words/expressions.
Example: Limit the length of text to 100 characters
<span wf-role="capped_text"
wf-maxlength="100"></span>
v7.4+ wf-maxlength-warning
Used in a text module, requires wf-maxlength to be set.
Shows a yellow warning upon reaching or exceeding a given percentage, just like wf-maxlength does in red. At 100% will show orange warning, informing users that beyond this limit, they cann no longer publish the content.
This directive can be used without a value, just like wf-new. This will use a default value of 90
Example: Limit the length of text to 100 characters and warn at 90% (90 characters).
<span wf-role="capped_warning_text"
wf-maxlength="100"
wf-maxlength-warning>
</span>
Example: Limit the length of text to 100 characters and warn at 75% (75 characters).
<span wf-role="capped_warning_text"
wf-maxlength="100"
wf-maxlength-warning="75">
</span>
wf-menu-item
Used on a <a>
element - usually a text module, to allow the text contents of the <a>
to be edited too. Hooks the given text submodule to link to either a category
, tag
or page
content models. Choosing one of these content models resets the others (only one is allowed at a time - to prevent confusion). When used on a module, it also hooks the contents of the module to these content model's titles (equivalent of wf-cm-text="[category.title, tag.title, page.title]"
)
Example: Linking to the default content models (categories, tags and articles):
<ul>
<li wf-role="menu_item">
<a wf-role="link"
wf-menu-item
></a>
</li>
</ul>
Value: the list of content models to link to, default category, tag, page
. Note: There is a manual
content model for having links to external contents only (e.g. for sponsor modules);
Example: Linking to specific content models (categories and tags in this example):
<ul>
<li wf-role="menu_item">
<a wf-role="link"
wf-menu-item="category,tag"
></a>
</li>
</ul>
Example: It's NOT mandatory to use wf-menu-item
on a module, it works on a simple <a>
element too. This can be useful for cases where the <a>
doesn't contain any text, editable or not, but it's positioned from CSS on top of a neighbouring image:
<div wf-role="sponsor"
wf-new>
<a wf-menu-item="manual"></a>
<img wf-filter="image_600_400"/>
</div>
Modifiers:
absolute
: generate absolute URIsno-cm-text
: by default the text module that haswf-menu-item
will be filled with the selected content model's title. Use this modifier to skip this behaviour and thus keep the manually entered text.
wf-module
Marks the current element as a module. Note that this is optional the wf-module-guesser wf-directive automatically fills in a value for wf-module
if one is not present.
Value: the type of module to be used.
Possible values:
body_text
multiline text module that allows formatting/linking parts of the textinline_text
single line text module (titles)composite
module that allows embedding content models and/or groupping one or more moduleslisting
allows configuring a dynamic article list (by category, template, author, tag, also by most read/shared, can also be configured to display search results)ad
allows picking an "advertising position", a slot where an ad will appearembed
allows embedding HTML from different providers (tweets, facebook posts, etc. or free html)
wf-multi-class
Same as wf-class, but allows choosing multiple options (checkboxes) instead of just one.
wf-module-guesser
This is a virtual wf-directive, it's being added automatically to all wf-role
elements that don't have a wf-module
attribute. Its role is to guess the module to use. It does so based on the following rules:
- Using the tag of the element:
h1
-h6
,span
anda
elements useinline_text
modulep
elements usebody_text
module
- For any other element:
- if the role of the module starts with
listing
,embed
orad
- it uses these as module composite
for all other cases
- if the role of the module starts with
wf-new
Used on module elements. Indicates whether the bound module should appear in a new article/board. A template can define any number of possible modules, but only some may be present in the initial state.
Example: Automatically add title
and paragraph
modules when creating new articles:
<h1 wf-role="title"
wf-new
></h1>
<p wf-role="paragraph"
wf-new
></p>
Value (optional, default 1
): the number of elements that should be added when the article/board is created
Example: Add 3 article
modules in a new board:
<div wf-role="article"
wf-new="3"
>
[[ page.title ]]
</div>
wf-not-sortable
Used on a module element. Excludes the module from the sorting interface. By default, every module can be sorted - moved up or down between its siblings or moved to a different container/board altogether. But in some cases, it makes sense limiting the number of modules that can be sorted. For example: inside a board that allows article
modules, one may want to limit the module sorting only to the article
modules themseleves and not allow its title
, image
, author_name
submodules to be sorted.
Example: Allow sorting only the article
module, remove its submodules from the sorting interface.
<div wf-role="article">
<h2 wf-role="title"
wf-not-sortable
></h2>
</div>
Value (optional, default: true
): this wf-directive allows a self
value. By default, wf-not-sortable
excludes the bound module and all of its children. When used with the self
value, it excludes only the bound module, allowing its children to still show. The self value is useful when a bigger/wrapping module is added to allow switching to different layouts. E.g. create a composite wrapping 3 article
composite modules, put it in the same wf-group
with a second one allowing 6 article
composite modules. The editor can then choose to switch between the 3 articles layout and the 6 articles one. In such case, it makes sense excluding the wrapper composite modules from the sorting interface, while still allowing the article
submodules to be sorted.
wf-popover-editor
Used on a module element. Allows one to use a custom component as the editor for the bound module. When present, it adds an edit button to the toolbar of the bound module. Clicking this icon will show a popover with its contents being rendered by the value component.
Example: Use the AppModuleEditorSample
component as the editor
<div wf-role="sample"
wf-popover-editor="AppModuleEditorSample"
></div>
wf-role
All wf-module
s must also have a wf-role
, indicating the role of the module. Details
wf-serializable
Used on a module element. Includes the given module when serializing the entity. Useful for when an article module is likely to be bound to an article module inside a board.
Example: Includes the branded
module in the serialized result of the article, uses it in an article
module inside a board
// inside the article template
<span wf-role="branded"
wf-serializable
></span>
// inside the board template
<div wf-role="article">
[[ page.branded ]]
</div>
wf-setting
A generic setting, displayed in the settings form either as radio or checkbox inputs. Its value can be accessed using the settings
object.
Example: Adds a image_size
setting and binds it to the wf-filter of the image
<div wf-role="image">
<wf-setting name="image_size">
<title>Image size</title>
<option value="">Default size</option>
<option value="portrait">Portrait</option>
<option value="landscape">Landscape</option>
</wf-setting>
<img wf-filter="settings.image_size || 'default_filter'" />
</div>
Note: See how the value for wf-filter
is an expression that also gives a default value. This is because for new pages (articles/boards) with this module, the image_size
setting wouldn't have any value, effectively leading to wf-filter
trying to apply the ""
(empty string) filter.
Example: Specifies the type of the setting, using the type
attribute:
<div wf-role="module">
<wf-setting name="selectSetting" type="select">
<title>Select an option</title>
<option value="">Default value</option>
<option value="value1">Value 1</option>
<option value="value2">Value 2</option>
</wf-setting>
<wf-setting name="radioSetting" type="radio">
<title>Select an option</title>
<option value="">Default value</option>
<option value="value1">Value 1</option>
<option value="value2">Value 2</option>
</wf-setting>
<wf-setting name="checkboxSetting" type="checkbox">
<title>Check this</title>
<option value="portrait">Portrait</option>
<option value="landscape">Landscape</option>
</wf-setting>
selectSetting: [[ settings.selectSetting ]]
radioSetting: [[ settings.radioSetting ]]
checkboxSetting: [[ settings.checkboxSetting ]]
</div>
Note: select
/radio
types should have a default empty value, it's the one to be checked when the editor doesn't select anything (e.g. when the module is new). checkbox
type does away with this requirement - when the module is new, the setting's value is empty, so no checkboxes will be checked.
wf-setting-element
A generic setting that gives the developer full control over the template used to render it.
Example: Defining a text input setting:
<script wfc-defaults>
const hasTextInputSetting = 0;
</script>
<div wf-role="module">
<wf-setting-element name="textInput">
<div v-if="wfc.hasTextInputSetting">
<div class="form-group">
<label :for="`text-input-setting-${wfRolePath.join('-')}`">
Text input setting
</label>
<div class="form-control">
<input :id="`text-input-setting-${wfRolePath.join('-')}`"
type="text"
:value="settings.textInput"
@input="commitSetting($event, 'textInput', $event.target.value)">
</div>
</div>
</div>
</wf-setting-element>
</div>
Note: See how the various variables available to the template are used:
wfRolePath
array is being used to generate a unique (within the document) ID for the input element, also used as thefor
attribute for thelabel
element, to make the input element focusable when clicking the labelsettings
object is used to bind the setting's value to the input elementcommitSetting
method is used to update the setting's value when the input element's value changeswfc
object is used in this case to check the value of a prop passed to the wf-component. In this case it renders the setting element conditionally, only if the prop was passed with a value of1
.isChecked
a util callback that can be used to tell whether a certain value is set for a certain setting.isChecked('setting-name', value)
Note: The example above defines a default prop value for the hasTextInputSetting
prop. This allows XalokNext to know that the prop type is Number
, simplifying the v-if
condition. Without this, the condition should've been v-if="wfc.hasTextInputSetting === '1'"
, since Boolean('0') === true
in JavaScript. This also assumes that the prop will be passed using the :
prefix when the wf-component is used (e.g. <wf-component :has-text-input-setting="1">
). See Number props for more details.
Additionally, a isChecked
function can be used to deal with array settings:
Example: Reimplementing <wf-setting type="radio">
using wf-setting-element
:
<div wf-role="module">
<wf-setting-element name="radioInput">
<div v-if="wfc.hasRadioInputSetting">
<div class="form-group">
<label>Radio Button</label>
<div class="form-check"
v-for="option in [
{id: '', label: 'Default'},
{id: 'a', label: 'A'},
{id: 'b', label:'B'}]">
<input type="radio"
class="form-check-input"
name="radio-setting"
:id="`radio-setting-${wfRolePath.join('--')}--${option.id}`"
:value="isChecked('radioInput', option.id)"
@input="commitSetting($event, 'radioInput', option.id)">
<label :for="`radio-setting-${wfRolePath.join('--')}--${option.id}`"
class="form-check-label">
[[option.label]]
</label>
</div>
</div>
</div>
</wf-setting-element>
</div>
wf-slider
Used on a module element. Same as wf-slide, but this must be used on the parent module.
IMPORTANT: A slider (wf-slider)
is a collection of slides (wf-slide)
. If you want to have multiple modules at the same level you must use wf-slide
.
Example:
<div wf-role="gallery"
wf-slider
>
<div class="slider-pane">
<div wf-role="slide"
wf-toolbar-position="bottom"
wf-new
>
<img wf-filter="slide" />
</div>
</div>
</div>
Note: Check the notes for wf-slide - they apply here too.
wf-slide
Used on a module element, submodule of a composite module. Indicates that the bound element should behave as a carousel slide. Using this wf-directive means that the parent module will allow selecting multiple content models, duplicating the wf-slide
bound module as many times as there are contents selected.
Example: Creates a carousel component:
<div wf-role="gallery">
<div class="slider-pane">
<div wf-role="slide"
wf-new
wf-toolbar-position="bottom"
wf-slide
>
<img wf-filter="slide" />
</div>
</div>
</div>
Note: wf-slide
and wf-slider
are mutually exclusive - using both of them is not allowed. Use either wf-slide
or wf-slider
.
Note: XalokNext comes bundled with the swipe library to handle carousels inside the admin. For the public part you must write the code to handle the carousels, as most projects require a lot of flexibility in setting up their sliders.
HTML structure requirements
Note the
<div class="slider-pane">
element above. This is required by swipe to make the sliders work in admin.If inside the
gallery
module you need another module, for example a gallery title, you must wrap the.slider-pane
element in another element. swipe requires that the.slider-pane
element is the first child of its container.
Example: Example gallery module containing a gallery title
<div wf-role="gallery">
<h3 wf-role="title"
wf-new
>
Enter gallery title here
</h3>
<div class="slider"> <!-- This element is required because the extra `title` module above,
the slider is going to be initialized on this element -->
<div class="slider-pane">
<div wf-role="slide"
wf-new
wf-toolbar-position="bottom"
wf-slide
>
<img wf-filter="slide" />
</div>
</div>
</div>
Without the title
module (or any other HTML not belonging to the slide), the slider would be initalized on the div[wf-role=gallery]
element. But since the first child of the gallery
element is not the slider-pane
(it's the title
module), one must add the additional .slider
element.
If one of the required elements (either .slider-pane
, or .slider
, if it's necessary) is missing, XalokNext is going to create them automatically for you - only in admin (the public-side HTML won't be affected). This might lead to unintentionally breaking how the CSS code is applied to the automatically generated HTML.
wf-slider-btn
Allows using a custom element to control the navigation of the slider. Useful if the public HTML already includes the prev/next buttons and you want to make these functional.
Note: If you set both the prev
and the next
buttons, the ones in the module's toolbar won't be shown.
Note: The button elements must have at least one unique (within the module) CSS class - it's used to target the button from JS code.
Example:
<div wf-role="gallery"
wf-slider
>
<div class="slider-pane">
<div wf-role="slide"
>
<img wf-filter="slide" />
</div>
</div>
<div class="navigation">
<div class="next" wf-slider-btn="next">Next slide</div>
<div class="prev" wf-slider-btn="prev">Previous slide</div>
</div>
</div>
wf-slider-options
Used on an element also bound with the wf-slider
wf-directive (or on the parent module of where the wf-slide
wf-directive is used). Pass the swipe options that will be used for controlling the carousel.
IMPORTANT: This must be used on the slider, not the slide! That is: the composite module that wraps the slide module.
Example: Make 3 slides appear and advance 3 at a time
<div wf-new
wf-role="slider"
wf-slider
wf-slider-options="{perPage: 3, slideSize: 3}"
>
<div wf-role="slide"
wf-new
>
<img wf-filter="slide" />
</div>
</div>
Note: The public CSS of you project likely sizes the <img>
tag accordingly. To test the above example without any CSS changes, add style="width: 100%; height: auto;"
to the <img>
tag, but consider putting this in the external CSS.
Example: Make 3 slides appear and advance 3 at a time with multiple modules inside at the same level
<div wf-new
wf-role="slider"
wf-slider-options="{perPage: 3, slideSize: 3}"
>
<div wf-new
wf-role="slide"
wf-slide
>
<img wf-filter="slide" style="width: 100%; height: auto;" />
</div>
<div wf-role="button_link"
wf-toolbar-position="top"
wf-new
>
<a wf-module="wfed/body_text/module"
wf-role="button_title"
wf-new
wf-menu-item
></a>
</div>
</div>
Note: In the above example, the slide
module is on the same level as the button_link
module. This is why we couldn't use wf-slider
on the parent module (role: slider
), wf-slider
works only if the slider has only one module. So the example uses wf-slide
on the slide
module instead, while still applying the wf-slider-options
on the parent module.
wf-soft-maxlength
Used on a text module element. Shows a character counter in the toolbar of the element (you have to make sure the toolbar is visible, that is, it does not use wf-toolbar-position="none"
). When the limit is reached, additional characters can be entered, but the bound module's background is changed to red, to indicate that the limit has been exceeded.
Example: Highlights the module when the entered text exceeds 100 characters:
<p wf-role="epigraph"
wf-soft-maxlength="100"
></p>
wf-toolbar-position
Used on a module element. Indicates the position of the module's toolbar, relative to the module's element. Useful when nesting multiple levels of modules, to prevent different levels toolbars from overlapping.
Example: show the toolbar to the left of the module.
<div wf-role="article"
wf-toolbar-position="left"
>
[[ page.title ]]
</div>
Value (default: top
): Can be one of:
- top
- right
- bottom
- left
- none
none
should be used to indicate that no toolbar should be shown for the bound module.
wf-use-placeholder
Used on a module element. Indicates that the module should keep showing on the SSR version (public side), even though it doesn't have any contents. By default, XalokNext removes the empty modules from the public side. This is in order to not show, for example, the placeholder image - if the editor didn't pick one.
Example: Shows the default value ("Services") if the editor doesn't change it:
<span wf-role="section_title"
wf-use-placeholder>
Services
</span>