Skip to content

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:

html
<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:

html
<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:

html
<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:

html
<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:

html
<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:

html
<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 the image_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.

html
<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:

html
<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!!!


html
{{ 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:

html
{{ 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:

html
{{ 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:

html
<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:

html
<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

html
<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.

html
<div wf-role="html"
     wf-module="embed"
     wf-embed-types="html"
></div>

Example: For multiple modules, use commas.

html
<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.

html
<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:

html
<div wf-role="embed"
     wf-facet="amp"
></div>

wf-filter

Used to bind

  • the src or srcset 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 for mode: outbound Imagine filters.

Example: bind the src attribute to the thumbnail URL corresponding to the image_600_480 Imagine filter.

html
<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:

html
<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:

html
<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 the alt attribute. In <picture> elements, the alt attribute is needed only for the <img>, not for each <source>
  • no-size: don't bind the width/height attributes.
  • absolute: bind the absolute URL of the thumbnail - by default it binds the relative URL.
  • v7.2 full-src: add data-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:

html
<p wf-formattings="b,i,u"></p>

Available formattings:

  • b: bold
  • u: underline
  • i: italic
  • ol: ordered list
  • ul: unordered list
  • a: link
  • s: strikethrough

There are also some shorthands available:

  • short: bold, underline, italic, strikethrough, link
  • lists: ordered and unordered lists
  • extended: includes short + lists

You can combine these options in any way you want:

html
<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:

html
<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:

html
<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:

html
<div wf-role="article">
  <a wf-href="page.category">[[ page.category?.title ]]</a>
</div>

Modifiers:

  • absolute: generate the absolute URL.

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:

text
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:

html
<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:

html
<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

html
<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

html
<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).

html
<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).

html
<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):

html
<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):

html
<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:

html
<div wf-role="sponsor"
     wf-new>
  <a wf-menu-item="manual"></a>
  <img wf-filter="image_600_400"/>
</div>

Modifiers:

  • absolute: generate absolute URIs
  • no-cm-text: by default the text module that has wf-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 text
  • inline_text single line text module (titles)
  • composite module that allows embedding content models and/or groupping one or more modules
  • listing 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 appear
  • embed 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 and a elements use inline_text module
    • p elements use body_text module
  • For any other element:
    • if the role of the module starts with listing, embed or ad - it uses these as module
    • composite for all other cases

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:

html
<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:

html
<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.

html
<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

html
<div wf-role="sample"
     wf-popover-editor="AppModuleEditorSample"
></div>

wf-role

All wf-modules 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

html
// 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

html
<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:

html
<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:

html
<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 the for attribute for the label element, to make the input element focusable when clicking the label
  • settings object is used to bind the setting's value to the input element
  • commitSetting method is used to update the setting's value when the input element's value changes
  • wfc 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 of 1.
  • 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:

html
<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:

html
<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:

html
<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

  1. Note the <div class="slider-pane"> element above. This is required by swipe to make the sliders work in admin.

  2. 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

html
<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:

html
<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

html
 <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

html
<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:

html
<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.

html
<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:

html
<span wf-role="section_title"
      wf-use-placeholder>
  Services
</span>