README
Vue-Pimcore Generator
node node_modules/.bin/vue-pimcore-generator --help
Elevator Pitch
Pimcore uses a WYSIWYG editor to edit documents which is incompatible with Vue components. To alleviate that, this generator opens a web page in the frontend, parses its contents, and creates Pimcore Areabricks. This is done using data attributes in Vue. Creating these Areabricks allows an editor to drag&drop components on a page and being able to see a preview within Pimcore which closely resembles the Vue frontend.
generator-definitions
This file defines which pages should be parsed by the Pimcore generator. To see the available options and their use, please see the generator-definitions.sample.js
file.
data-pimcore-*
attributes
Supported data-pimcore-areabrick
The name that should be used for the area brick in Pimcore. Only [a-z] are allowed.data-pimcore-arg
Optional arguments for the Twig tag, e.g. see https://pimcore.com/docs/6.x/Development_Documentation/Documents/Editables/Relation_(Many-To-One).html#page_Using-Restrictiondata-pimcore-identifier
The field name of the Twig tag (e.g.thisisthename -> pimcore_input('thisisthename')
) and entry in the data object. Only [a-z_] are alloweddata-pimcore-disable-editmode
Recursively adds thedisabled
attribute<a>
tags when in Pimcore's edit mode. Was added to prevent navigation usage in Pimcore's edit mode.data-pimcore-type
Type of the CMS editor input type and Twig tag (e.g.input -> pimcore_input('name')
), see list of editablesdata-pimcore-document
defines the path to the twig file after the build (e.g.snippets/my_snippet
) AND source url of the data for GraphQL.data-pimcore-snippet="<name>"
Defines the root element of a snippet template.
Examples
Snippet (complete example)
c-header.vue
This is the only file you write by hand.
<!-- A layout -->
<b-jumbotron
:class="b()"
:header-level="5"
lead-tag="div"
data-pimcore-type="snippet"
data-pimcore-identifier="header"
data-pimcore-snippet="header"
:data-pimcore-document="path">
<template v-slot:header>
<div v-if="pimcoreDocumentReady"
v-html="elements.headline.text"
:class="b('header')"
data-pimcore-identifier="headline"
data-pimcore-type="input"></div>
</template>
<template v-slot:lead>
<div v-if="pimcoreDocumentReady"
v-html="elements.content.text"
:class="b('lead')"
data-pimcore-identifier="content"
data-pimcore-type="wysiwyg"></div>
</template>
</b-jumbotron>
Rendered HTML
Generated by the browser.
<div
data-pimcore-type="snippet"
data-pimcore-identifier="header"
data-pimcore-snippet="header"
data-pimcore-document="/snippets/header_shared"
class="jumbotron c-header">
<h1 class="display-5">
<div
data-pimcore-identifier="headline"
data-pimcore-type="input"
class="c-header__header">
Pimcore-CaaS-Vue-SPA-PWA-PoC!
</div>
</h1>
<div class="lead">
<div
data-pimcore-identifier="content"
data-pimcore-type="wysiwyg"
class="c-header__lead">
<p>
Viel Spass!
</p>
</div>
</div>
</div>
Main Twig template
<div
data-pimcore-document="/snippets/header_shared"
class="jumbotron c-header">
{{ pimcore_snippet('header') }}
</div>
snippets/header_shared.html.twig
Snippet Twig template at (Actually, three files are generated to have different view for editmode and viewmode.)
<h1 class="display-5">
<div class="c-header__header">{{ pimcore_input('headline') }} </div>
</h1>
<div class="lead">
<div class="c-header__lead">{{ pimcore_wysiwyg('content') }} </div>
</div>
Pimcore Twig Tags
This Vue code:
<div data-pimcore-identifier="headline" data-pimcore-type="input"></div>
becomes this Twig code
<div>{{ pimcore_input('headline') }}</div>
Please see the Pimcore docs for which data-pimcore-type
s are supported. The identifier can be any string and generally, snake_case or camelCase are used. kebab-case might lead to troubles dealing with GraphQL responses. And spaces are evil, weallknowthat.
Additionally, a (second) argument can be passed to the Twig tag using data-pimcore-arg
such as this example where a relation is restricted to Product
objects:
<div data-pimcore-type="relations"
data-pimcore-identifier="products"
data-pimcore-arg='{
"types": ["object"],
"subtypes": {
"object": ["object"],
},
"classes": ["Product"]
}'
:class="b('productgrid')">
</div>
Produce this Twig template:
<div class="c-areablock__productgrid">
{{ pimcore_relations('products', {
"types": ["object"],
"subtypes": {
"object": ["object"],
},
"classes": ["Product"]
})
}}
</div>
Pimcore Areablocks and Bricks
Render mode
The only difference to normal Twig tags is: data-pimcore-areabrick
on the parent.
<div v-for="block in elements"
:key="block._tagName"
:data-pimcore-areabrick="block._type">
<div v-if="block._type === 'headline'">
<e-heading tag-name="h2"
:data-pimcore-type="block.content._tagType"
data-pimcore-identifier="content">
{{ block.content.text }}
</e-heading>
</div>
<!-- Add more bricks -->
</div>
Adding-a-new-brick mode
Simply add the brick unconditionally and execute the generator.
<div v-for="block in elements"
:key="block._tagName"
:data-pimcore-areabrick="block._type">
<c-new-component
data-pimcore-type="brickname"
data-pimcore-identifier="content">
Lorem ipsum
</c-new-component>
<!-- Rest of the loop -->
</div>
Note: the name of the Vue component is irrelevant. (The parsing happens in a browser at which stage the Vue component names are no longer visible.)