npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@teclead/aem-generator

v3.2.0

Published

AEM Dialog and Component Generator based on Typescript Interfaces

Downloads

517

Readme

AEM Dialog Generator

This project contains the Custom Dialog Generator for AEM. The Library provides the creating of all necessary AEM Files (XML, HTML) to create an AEM component based on a TypeScript file, which describes the structure of the dialog and the component

Development

The library can be run by executing builder.js. It is recommended to implement a script in the package.json, that looks like this

“build:dialogues”: “node node_modules/@teclead/aem-generator/builder.js”,

Building the dialogues can then be executed by running

npm run build:dialogues

Touch UI fields

The default props for the touch ui fields will be define with TouchUIFieldOptionKeysEnum.model.ts Expand the default props with the enum

API

The following example shows a *.dialog.ts file with the necessary configuration for the creating of an AEM component.

Full Example

import {
  TouchUIDialogFieldOptions,
  TouchUIDialogTab,
  TouchUIField,
  AEMTouchUIDialog
} from '@teclead/aem-generator/models';

import {
  TouchUIXMLGenerator
} from '@teclead/aem-generator';

const fields: TouchUIDialogFieldOptions[] = [
  {
    label: 'Mein Textfeld',
    type: TouchUIField.Text,
    databaseName: 'label',
    isRequired: true,
    description: 'Meine Beschreibung für Textfeld...'
  },
  {
    label: 'Mein PathField',
    type: TouchUIField.Path,
    databaseName: 'path',
    description: 'Meine Beschreibung für PathField...',
  },
  ...]


const tabs: TouchUIDialogTab[] = [
  { title: 'Mein erstes Tab', fields },
  {
    title: 'Mein zweites Tab',
    fields: [
      {
        label: 'Mein Touch UI Multifield',
        type: TouchUIField.Multifield,
        description: 'Meine Beschreibung für das Multifield...',
        databaseName: 'multitouchuidatabase',
        multifieldtype: TouchUIField.Text
      }
    ]
  },
  ...]


export const dialog: AEMTouchUIDialog = {
  sightlyTemplate: ReactTemplate, // HTML String
  componentName: 'MyTestComponent',
  componentGroup: 'MyTestGroup',
  componentDescription: 'MyTestComponentDescription',
  componentPath: './src/__tests___/results/touchUI',
  tabs,
  resourceSuperType: 'core/wcm/components/text/v2/text',
};

new TouchUIXMLGenerator(dialog).writeFilesToAEM();

By default, if you add a component, which uses this generator, the page in AEM will do a page refresh after inserting the component. This will guarantees, that the react component will be available immediately after adding the component to your page. To disable this behaviour, simply set the property disableRefresh: true inside the AEMTouchUIDialog object.

Fields

The variable fields: TouchUIDialogFieldOptions[] describes the individual fields of the Dialog. label, type, databaseName are always required, all additional configurations are optional and also based on the selected type. To select the Type the TouchUiField-Object should be include and the wanted field-type needs to be selected in the properties. You can add custom additional common keys for own implementations on touch ui dialog field level.

The hide property is optional and can be used to hide a dialog field inside a specific condition. This property uses a function where return a boolean.

const fields: TouchUIDialogFieldOptions[] = [{
    label: 'Mein Button',
    type: TouchUIField.Button,
    'acs-commons-nested': "JSON_STORE",
    databaseName: 'btn',
    javaScriptHandler: 'alert(123)',
    hide: ({contentPath: '/path/to/content'}) => contentPath.includes('/to'),
},
...
];

The onLoad property is optional and can be used to execute a function after the dialog is loaded. This property uses a function where return a void.

const fields: TouchUIDialogFieldOptions[] = [{
    label: 'Mein Button',
    type: TouchUIField.Button,
    databaseName: 'btn',
    onLoad: ({ contentPath }) => {
      console.log(contentPath);
    },
},
...
];

The onChange property is optional and can be used to execute a function after a TouchUI field has changed. This property uses a function where return a void. The targetElement is an HTMLElement or an array of HTMLElements which can be used to manipulate the DOM. To get this to work, you need to setup the field onChangeTarget and if you want to use a custom class name, you have to set the property className in the target field.

const fields: TouchUIDialogFieldOptions[] = [
  {
    label: 'Mein Dropdown',
    type: TouchUIField.Dropdown,
    databaseName: 'dropdown',
    onChange: ({ contentPath, targetElement }) => {
      console.log(contentPath, targetElement);
    },
    onChangeTarget: 'my-button-class',
  },
  {
    label: 'Mein Button',
    type: TouchUIField.Button,
    databaseName: 'btn',
    className: 'my-button-class',
  }
...
];

For further information check out the individual interfaces for the different field types.

Side-Node: The button offers to execute javaScript code with the onClick listener by adding the javaScriptHandler-Property.

The variable tabs: TouchUiDialogTab[] describes the required tabs for the dialog, it hold a title and a field property. The field property should hold the value of the fields: TouchUIDialogFieldOptions[] variable. If more than one tab is used, then obviously more than one fields: TouchUIDialogFieldOptions[] variable needs to be configured. The hide property is optional and can be used to hide a tab inside a specific condition. This property uses a function where return a boolean.

const tabs: TouchUIDialogTab[] = [
  { title: 'Mein erstes Tab', fields, hide: ({contentPath: '/path/to/content'}) => contentPath.includes('/to') },
  ...
]

The sightlyTemplate variable is referencing the HTMl-Template that is used to build the AEM component. It is mandatory to create this reference on a component Level.

const sightlyTemplate = '<h1>my custom template...</h1>';

The exampleTouchUiDialog: AEMTouchUIDialog variable describes the configuration of the AEM component. It holds the reference to the sightlyTemplate, the component name, the component group, the component description, tabs and the component path (destination path) as required inputs and a couple of optional properties than can be configured. For more Information check out the Interfaces.

export const exampleTouchUIDialog: AEMTouchUIDialog = {
  sightlyTemplate: sightlyTemplate,
  componentName: 'MyTestComponent',
  componentGroup: 'MyTestGroup',
  componentDescription: 'MyTestComponentDescription',
  componentPath: './src/__tests___/results/touchUI',
  tabs: tabs,
};

Full example for a simple component

import { AEMTouchUIDialog, TouchUIField } from '@teclead/aem-generator/models';
import { TouchUIXMLGenerator } from '@teclead/aem-generator';
import {
  COMPONENTPATH,
  COMPONENT_GROUP,
  REACT_TEMPLATE,
} from '../Commons/commons';

const dropDownOptions = [
  { value: 'val1', name: 'Label 1' },
  { value: 'val2', name: 'Label 2' },
];

export const ctaDialog: AEMTouchUIDialog = {
  componentPath: COMPONENTPATH + 'ctaReact',
  sightlyTemplate: REACT_TEMPLATE,
  componentName: 'Button-React',
  componentGroup: COMPONENT_GROUP,
  tabs: [
    {
      title: 'My first Tab',
      fields: [
        { label: 'Text field', databaseName: 'text', type: TouchUIField.Text },
        {
          label: 'Text Area',
          databaseName: 'textArea',
          type: TouchUIField.TextArea,
        },
        {
          label: 'Dropdown field',
          databaseName: 'dropdown',
          type: TouchUIField.Dropdown,
          options: dropDownOptions,
        },
        { label: 'Pathfield', databaseName: 'path', type: TouchUIField.Path },
        {
          label: 'Checkbox',
          databaseName: 'check',
          type: TouchUIField.Checkbox,
        },
        { label: 'Image', databaseName: 'img', type: TouchUIField.Imagefield },
      ],
    },
  ],
};

new TouchUIXMLGenerator(ctaDialog).writeFilesToAEM(); // will write the files when npm build:dialogues is called

TouchUIXMLGenerator extended

The TouchUIXMLGenerator can be extended for own implementation on touch ui dialog field level for this you can add custom additional common keys e.g. acs-commons-nested, inside TouchUIDialogFieldOptions

const tabs = [
  {
    title: 'Mein viertes Tab',
    fields: [
        {
          label: 'Nested Multifield with JSON storage',
          databaseName: 'multi',
          type: TouchUIField.MultifieldNested,
          'acs-commons-nested': "JSON_STORE",
          multifieldOptions: [ ... ]
        },
        ...
    ]
  },
  ...
]

class DialogGenerator extends TouchUIXMLGenerator {

  public getFields(fields: TouchUIDialogFieldOptions[]) {
      const template =  super.getFields(fields);

      if (this.has('acs-commons-nested')) {
        return this.replaceResourceType(template,  'container', 'granite/ui/components/foundation/form/fieldset');
      }

      return template;
  }
}
const dialog: AEMTouchUIDialog = {
  componentPath: COMPONENTPATH + "ctaReact",
  sightlyTemplate: REACT_TEMPLATE,
  componentName: "Button-React",
  componentGroup: COMPONENT_GROUP,
  tabs
}

new DialogGenerator(dialog).writeFilesToAEM();

Contributing

If you want to contribute on this project, check out our Contribution Guidelines.