Skip to content

Blocks in eWizard.js projects

A block is a fundamental component in eWizard that serves as a container for other components. Blocks provide a structured way to organize content and are essential for developing different types of eWizard content items.

Key features:

  • Consistency: blocks provide structure across your content items.
  • Customization: you can customize blocks for specific content items.
  • Reusability: a developed block is available for reuse, making development more efficient.
  • Simplicity: with blocks, content item editing in eWizard Editor is easier.
  • Modular approach: blocks in content items streamline modular approach to content development.
  • Generating email templates using eVa AI.

You can add local blocks to your project or use blocks from eWizard.js repository for emails, e-Detailers, and sites.

Local vs. eWizard.js repository blocks

While both ways to use blocks are available, you cannot combine them in the same content item.

Block directory structure

A local block consists of a directory with at least two essential files:

  • index.vue: Contains the block template with the Vue component code
  • icon.png: The block image that appears in eWizard Editor

The block directory can also include other common assets and media files specific to that block.

Configuration

To use blocks in your eWizard projects, configure the path to the local blocks in the ./.ewizard/settings.json file:

json
// ./.ewizard/settings.json

{
  "path": {
    "blocks": "common/blocks-library",
    "blocksFilename": "blocks.json",
    "blocksManifest": "common/blocks-library/blocks.json"
  }
}

Where:

  • blocks is the path to the directory where blocks are stored (typically common/blocks-library)
  • blocksFilename is the name of the file that defines which blocks appear in eWizard Editor (default: blocks.json)
  • blocksManifest is the full path to the file that defines what blocks appear in eWizard Editor (default: common/blocks-library/blocks.json)

Adding local blocks

To add local blocks, do the following:

  1. Remove all existing blocks from the blocks.json file.
  2. Remove all blocks from template's node_modulea/2blocks in the App.vue file.

Then, follow these steps:

  1. Configure the paths in ./.ewizard/settings.json.

  2. Add the block directory to ./common/blocks-library.

  3. Ensure the block directory contains the required index.vue and icon.png files.

  4. Add your blocks as objects to the components array in ./common/blocks-library/blocks.json:

    json
    {
       "components": [
          {
             "id": "header-block-1",
             "name": "Header block 1",
             "icon": "/common/blocks-library/header-block-1/icon.png"
          },
          {
             "id": "body-block-1",
             "name": "Body block 1",
             "icon": "/common/blocks-library/body-block-1/icon.png"
          },
          {
             "id": "footer-block-1",
             "name": "Footer block 1",
             "icon": "/common/blocks-library/footer-block-1/icon.png"
          }
       ]
    }

    Here, you can also configure groups and filters to organize blocks on the layout.

  5. Archive the project with wiz archive.

  6. Upload the zipped project to eWizard Editor and add the block to your content item layout.

Initializing a block with eWizard CLI

You can also initialize an empty block template with eWizard CLI. Blocks initialized with eWizard CLI, contain all required files immediately after initialization.

eWizard.js repository blocks

For email and site projects, you can also use blocks from eWizard.js repository:

To use blocks from eWizard.js repository:

  1. Add block dependencies to your project's package.json.
    To install a specific block version, specify it at the end of the block's line after #.

    json
    {
      "dependencies": {
      "@blocks/content-2a": "git+https://git.qapint.com/ewizardjs/email/blocks/content-2a.git#1.1.0",
     "@blocks/content-2b": "git+https://git.qapint.com/ewizardjs/email/blocks/content-2b.git"
     }
    }
  2. Run wiz install to install your blocks to node_modules/@blocks.

  3. Add installed blocks to your project's blocks.json to make them usable in eWizard Editor.

  4. Register your blocks in ./extensions/globalBlocks.js:

    js
    import { requireCurrentBlocks } from 'ewizardjs';
    
    const blocks = requireCurrentBlocks();
    
    export default function (Vue) {
      blocks.forEach((block) => {
        Vue.component(block.name, block);
      });
    }

Read about editing blocks in eWizard Editor.

e-Detailer blocks

By default, a scaffolding e-Detailer template has one pre-built block—the module placeholder. The module placeholder block is used to upload modules from Veeva Vault.

You can configure local (custom) blocks in e-Detailers in the following ways:

  1. Following the steps for adding local blocks.

    Local block dependencies

    This way, you don't need to add the dependencies for your local e-Detailer block. However, if your local block relies on other eWizard components, you still need to add these dependencies to the packaje.json.

    Conflicting paths

    By detault, path.blocks point to node_modules/@blocks. After changing the path to blocks, you will be unable to use the module placeholder.

  2. Adding your required blocks to node_modules/@blocks and updating the dependencies.

Dependencies and registration

To use blocks in e-Detailers:

  1. Add the dependencies for the wiz-block and module-placeholder components to the package.json:
json
// ./package.json
{
  "dependencies": {
    "@blocks/module-placeholder": "git+https://git.qapint.com/ewizardjs/edetailer/blocks/module-placeholder.git#1.0.2",
    "wiz-block": "git+https://git.qapint.com/ewizardjs/edetailer/components/wiz-block.git#1.0.1"
  }
}
  1. Install the components:
shell
wiz install
  1. Register the components globally in the ./extensions/globalComponent.js file:
js
// ./extensions/globalComponent.js

import wizBlock from 'wiz-block';
import modulePlaceholder from '@blocks/module-placeholder';

export default (Vue) => {
  Vue.component('wiz-block', wizBlock);
  Vue.component('module-placeholder', modulePlaceholder);
};

Email blocks

In emails, it's recommended to use the wiz-placeholder component within blocks to create a structured layout:

html
<wiz-block class="block content-2j m-p-lr-0" style="padding: 20px 45px;">
  <wiz-placeholder class="m-full-width">
    <wiz-column :width="100">
      <wiz-title class="m-p-lr-20" :text="$t('title')"></wiz-title>
      <wiz-text class="m-p-lr-20" :text="$t('main_text1')" style="padding-top: 15px;"></wiz-text>
    </wiz-column>
  </wiz-placeholder>
  <wiz-divider class="m-p-lr-20" divider-color="#0084c4" :divider-height="2" style="width: 100%; padding: 40px 0 0;"></wiz-divider>
</wiz-block>

Creating AI-ready blocks

In emails, you can adjust blocks to be compatible with eVa AI. Once an email with AI-compatible blocks is uploaded to eWizard, users can create email templates based on it. This allows users to quickly generate customized email variations using AI-powered prompts.

To create an AI-compatible block, add the description and type fields to the required block in email's blocks.json file. For example:

json
{
   "components": [
      {
         "id": "header-block",
         "name": "Header block",
         "description": "Decorative header block. Should be included at the beginning of an email. Should not be assigned any values",
         "type": "header",
         "path": "./common/blocks-library/header-block"
      }
   ]
}

Rules for creating effective block descriptions:

  1. Describe blocks in terms of generic element types, not specific element instances that are not defined with an Element Type in eWizard Editor. Treat unspecified elements as if they aren't present.

    • Reason: The eVa AI agent relies on these declared element types to understand the overall structure and purpose of the block. Overly specific descriptions without element types hinder the AI's ability to generalize and create variations.
    • Examples:
      • Less effective: "This block contains a specifically named image and some text"
      • More effective: "This block contains an image element and a text element"
  2. Avoid using terms like "footnote" or "disclaimer" when describing blocks containing small, supplementary text. Instead, describe the content's function or appearance.

    • Reason: Describing the function ensures the AI identifies the element regardless of terminology.
    • Examples:
      • Less effective: "This block contains a footnote with copyright information"
      • More effective: "This block contains a small text section for copyright information"
  3. Keep descriptions concise. Aim for one or two short, clear sentences that capture that capture the block's primary purpose and structure.

    • Reason: Concise descriptions help the AI quickly grasp the key characteristics of the block without being bogged down in unnecessary detail.

Example descriptions

  • Header block: "Decorative header block. Should be included at the beginning of an email. Should not be assigned any values."
    Focus: purpose
  • Footer block: "Decorative footer block. Should be included at the end of an email. Should not be assigned any values."
    Focus: purpose
  • Body blocks (describe the structure and the element order): "A body block with two text columns located one after another horizontally. An image is located under the columns."
    Focus: arrangement of element types

Messenger ad blocks

Messenger ad blocks typically include a more specific structure optimized for messenger platforms:

html
<wiz-block class="messenger-ad-block-01">
    <div class="wrapper">
        <wiz-text
                class="title py-8 px-5"
                :text="$t('title', { textColorToken: '#2E4FFF', fontFamilyToken: 'OpenSans' })"
        ></wiz-text>
        <wiz-text
                class="subtitle px-5"
                :text="$t('subtitle', { textColorToken: '#150E52', fontFamilyToken: 'OpenSans' })"
        ></wiz-text>
        <wiz-text
                class="text pt-6 pb-7 px-5"
                :text="$t('text1', { textColorToken: '#150E52', fontFamilyToken: 'OpenSans' })"
        ></wiz-text>
        <wiz-image
                src="./media/images/image.png"
                align="center"
                alt="Image"
        ></wiz-image>
    </div>
</wiz-block>

The messenger ad scaffolding template includes a default-block directory. You can use it as a starting point for creating new blocks.

Site blocks

A site block's index.vue file includes the following tag sections:

  • <i18n> with localization texts
  • <template> defines the block layout (must include the <wiz-block> tag)
  • <style> specifies CSS styles (avoid using CSS ID selectors for proper display in eWizard Editor)
  • <script> with JavaScript for the block
html
//@formatter:off
<i18n>
    {
      "eng": {
        "title": "<h2><span style='color: {colorToken};'>Lorem ipsum dolor sit amet, consectetur</span></h2>",
        "button": "<p><span style='color: {colorToken};'>BUTTON</span></p>"
      }
    }
</i18n>
//@formatter:on

<template>
    <wiz-block class="body-block-1">
        <wiz-placeholder>
            <wiz-column :width="50">
                <wiz-text :text="$t('title', { colorToken: $theme.color2 })"></wiz-text>
            </wiz-column>
            <wiz-column :width="50">
                <wiz-button :width="115" :height="48" :text="$t('button', { colorToken: $theme.color10 })"></wiz-button>
            </wiz-column>
        </wiz-placeholder>
    </wiz-block>
</template>

<script>
    export default { name: 'body-block-1' };
</script>

<style lang="scss">
  .root .body-block-1 {
    // styles
  }
</style>

Block groups and filters

Add block groups and filters to organize them in eWizard Editor, making them easier to find and use.

To define a block group, add the groups array to your /common/blocks-library/blocks.json and map the blocks to groups:

json
{
  "groups": [
    {
      "id": "hero-banners",
      "field": "groups",
      "name": "Hero banners"
    },
    {
      "id": "product-content",
      "field": "groups",
      "name": "Product content"
    }
  ]
}

To define block filters, add the filters array to common/blocks-library/blocks.json as follows:

json
{
  "filters": [
    {
      "id": "cardiocare",
      "field": "filters",
      "name": "CardioCare"
    },
    {
      "id": "respirex",
      "field": "filters",
      "name": "Respirex"
    }
  ]
}
KeyDescription
idGroup or filter identifier
fieldObject category. One of: filters, groups
nameGroup or filter display name for eWizard Editor

Map your required blocks with groups and filters:

json
{
  "components": [
    {
      "id": "herobanner-1",
      "name": "Hero Banner 1",
      "icon": "common/blocks-library/herobanner-1/icon.png",
      "groups": "hero-banners",
      "filters": [
        "respirex",
        "cardiocare"
      ]
    },
    {
      "id": "productinfo-1",
      "name": "Product Info 1",
      "icon": "common/blocks-library/productinfo-1/icon.png",
      "groups": "product-content",
      "filters": "respirex"
    },
    {
      "id": "dosage-1",
      "name": "Dosage Block 1",
      "icon": "common/blocks-library/dosage-1/icon.png",
      "groups": "product-content",
      "filters": "cardiocare"
    }
  ]
}
KeyDescription
idBlock identifier
nameBlock display name
iconPath to the block icon file
groupsAn identifier of the group holding the block
filtersAn identifier of the filter applicable to the block

For emails and messenger ads, you can additionally configure filtering by brand. For this, add the brands array the same way as filters and groups and set up mapping with required blocks.

Theme-based blocks

You can use a dynamic list of blocks for the applied dynamic themes.

A dynamic list of blocks means that blocks available on the Blocks tab of the eWizard Editor elements panel depend on the selected theme or target CLM system.

Map blocks with the required themes in ./common/blocks-library/blocks-themes.json as follows:

json
{
  "themes": {
    "viseven": {
      "blocks": [
        {
          "id": "header-block-1",
          "name": "Header block 1",
          "icon": "/themes/viseven/media/images/blocks-icons/header-block-1.png"
        },
        {
          "id": "footer-block-viseven-1",
          "name": "Footer block 1",
          "icon": "/themes/viseven/media/images/blocks-icons/footer-block-viseven-1.png"
        }
      ],
      "defaultBlocks": [
        "header-block-1",
        "footer-block-viseven-1"
      ]
    },
    "unbranded": {
      "blocks": [
        {
          "id": "header-block-1",
          "name": "Header block 1",
          "icon": "/themes/unbranded/media/images/blocks-icons/header-block-1.png"
        },
        {
          "id": "footer-block-1",
          "name": "Footer block 1",
          "icon": "/themes/unbranded/media/images/blocks-icons/footer-block-1.png"
        }
      ],
      "defaultBlocks": [
        "header-block-1",
        "footer-block-1"
      ]
    }
  }
}
FieldTypeDescriptionRequired
theme-name.blocksarrayThe array with blocks for the theme-name themeRequired
blocks.idstringBlock identifierRequired
blocks.namestringBlock name to display in eWizard EditorRequired

To display the list of blocks for the specific theme, select this theme as current in the settings.json file.

Default blocks

The default blocks are displayed on the content item layout of eWizard Editor by default. They're predefined by the selected theme.

To add default blocks to your site template:

  1. In the ./common/blocks-library/blocks-themes.json, add your required blocks to the defaultBlocks array.
    Make sure you're adding them to your required theme. For instance, viseven.defaultBlocks or unbranded.defaultBlocks as shown in the example:
json
{
  "themes": {
    "viseven": {
      "blocks": [
        {
          "id": "header-block-1",
          "name": "Header block 1",
          "icon": "/themes/viseven/media/images/blocks-icons/header-block-1.png"
        },
        {
          "id": "footer-block-viseven-1",
          "name": "Footer block 1",
          "icon": "/themes/viseven/media/images/blocks-icons/footer-block-viseven-1.png"
        }
      ],
      "defaultBlocks": [
        "header-block-1",
        "footer-block-viseven-1"
      ]
    },
    "unbranded": {
      "blocks": [
        {
          "id": "header-block-1",
          "name": "Header block 1",
          "icon": "/themes/unbranded/media/images/blocks-icons/header-block-1.png"
        },
        {
          "id": "footer-block-1",
          "name": "Footer block 1",
          "icon": "/themes/unbranded/media/images/blocks-icons/footer-block-1.png"
        }
      ],
      "defaultBlocks": [
        "header-block-1",
        "footer-block-1"
      ]
    }
  }
}

Alternatively, you can specify default blocks as a named list for additional filtering:

json
{
  "themes": {
    "viseven": {
      "blocks": [
        {
          "id": "header-block-1",
          "name": "Header block 1",
          "icon": "/themes/viseven/media/images/blocks-icons/header-block-1.png"
        },
        {
          "id": "footer-block-viseven-1",
          "name": "Footer block 1",
          "icon": "/themes/viseven/media/images/blocks-icons/footer-block-viseven-1.png"
        }
      ],
      "defaultBlocks": {
        "$default": [
          "default-block-1"
        ],
        "header": [
          "header-block-1"
        ]
      }
    }
  }
}

When name is skipped, the blocks from the $default array are displayed on the layout.

  1. In your project's App.vue, define your block name under DynamicBlocksLoader.
    For a multipage sites and e-Detailers, add the index.vue file of your required site page or e-Detailer slide.
html
<template>
    <wiz-page>
        <DynamicBlocksLoader
                :blocks-themes="blocksThemes"
                :blocks-list="blocksList"
                name="header-block-1"
        ></DynamicBlocksLoader>
    </wiz-page>
</template>
  1. Proceed with archiving and uploading your project to eWizard Library.

Module placeholders

In emails and e-Detailers, you can use the module placeholder block. It's an eWizard.js repository block designed as a placeholder for Veeva Vault approved modules.

To have a module placeholder in your project, do the following:

  1. Add module-placeholder and wiz-block to package.json:
json
"@blocks/module-placeholder": "git+%link-to-your-required-module-placeholder"%
"@blocks/wiz-block": "git+%link-to-your-required-wiz-block"%
  1. Add module-placeholder to ./common/blocks-library/blocks.json as follows:
json
{
  "components": [
    {
      "id": "module-placeholder",
      "name": "Module Placeholder",
      "model": {},
      "icon": "node_modules/@blocks/module-placeholder/icon.png",
      "metadata": []
    }
  ]
}
FieldTypeDescription or valueRequired
idstringmodule-placeholder, the identifier of the module placeholderRequired
namestringYour module placeholder display nameRequired
modelobjectOptional
iconstringPath to the icon image for the module placeholderRequired
metadataarray of stringsMetadata keywords to be used in Veeva VaultOptional

Read more

Dynamic list of blocks