UNPKG

@silexlabs/silex-cms

Version:

Silex plugin

246 lines (239 loc) 9.99 kB
import { DataSourceEditor, removeState, setState, toExpression } from '@silexlabs/grapesjs-data-source' import { ClientConfig } from '@silexlabs/silex/src/ts/client/config' //import { ClientEvent } from '@silexlabs/silex/src/ts/client/events' import { EleventyPluginOptions, Silex11tyPluginWebsiteSettings } from '../client' import { html, TemplateResult } from 'lit-html' import { Page } from 'grapesjs' import { WebsiteSettings } from '@silexlabs/silex/src/ts/types' /** * Main function to add the settings to the page */ export default function(config: ClientConfig, opts: EleventyPluginOptions): void { if(!opts.enable11ty) return // Do not add the settings if 11ty is disabled config.on('silex:startup:end', () => { const editor = config.getEditor() as DataSourceEditor editor.on(/* ClientEvent.SETT(INGS_SAVE_START */'silex:settings:save:start', (page: Page) => updateBodyStates(editor, page)) config.addSettings({ id: 'cms', label: 'CMS', render: (settings: WebsiteSettings, page: Backbone.Model) => render(settings, config, page as unknown as Page), // FIXME: make sure Page is a Backbone.Model }, 'page') }) } /** * Set the state on the body component * This is only useful to build the GraphQL query */ function stateOnBody(editor, value, name, body) { if (value) { const expression = toExpression(value) if(expression) { setState(body, name, { label: name, hidden: true, expression, }) } else { console.error(`Invalid JSON for ${name}`) removeState(body, name) editor.runCommand('notifications:add', { type: 'error', message: `Invalid JSON for ${name}`, group: 'Errors in your settings', }) } } else { removeState(body, name) } } function showWarningDirty() { document.getElementById('pageination-data-changed')?.classList.remove('silex-hidden') } function hideWarningDirty() { document.getElementById('pageination-data-changed')?.classList.add('silex-hidden') } /** * Set the state on the body component * This is only useful to build the GraphQL query */ function updateBodyStates(editor: DataSourceEditor, page: Page) { hideWarningDirty() if (page) { const settings = page?.get('settings') as Silex11tyPluginWebsiteSettings | undefined if (settings) { const body = page.getMainComponent() stateOnBody(editor, settings.eleventySeoTitle, 'eleventySeoTitle', body) stateOnBody(editor, settings.eleventySeoDescription, 'eleventySeoDescription', body) stateOnBody(editor, settings.eleventyFavicon, 'eleventyFavicon', body) stateOnBody(editor, settings.eleventyOGImage, 'eleventyOGImage', body) stateOnBody(editor, settings.eleventyOGTitle, 'eleventyOGTitle', body) stateOnBody(editor, settings.eleventyOGDescription, 'eleventyOGDescription', body) stateOnBody(editor, settings.eleventyPageData, 'eleventyPageData', body) stateOnBody(editor, settings.eleventyPermalink, 'eleventyPermalink', body) } } } /** * Render the settings form */ function render(settings: Silex11tyPluginWebsiteSettings, config: ClientConfig, page: Page): TemplateResult { setTimeout(() => { // Update the settings form when the selection changed without recreating the form (document.querySelectorAll('#settings-cms input') as NodeListOf<HTMLInputElement>) .forEach((input: HTMLInputElement) => { switch (input.type) { case 'checkbox': input.checked = !!settings[input.name] break default: input.value = settings[input.name] ?? '' } }) }) const body = page.getMainComponent() return html` <style> .silex-warning { margin-top: 10px; padding: 10px; background-color: var(--ds-primary); border-color: var(--ds-button-color); color: #721c24; border: 1px solid transparent; border-radius: .25rem; } </style> <div id="settings-cms" class="silex-hideable silex-hidden"> <div class="gjs-sm-sector-title">Silex CMS - Page settings</div> <div class="silex-help"> The "Silex CMS" feature integrates <a target="_blank" href="https://www.11ty.dev/">11ty</a> static site generator and your favorite headless CMS with Silex. <br>Read the <a target="_blank" href="https://docs.silex.me/en/user/cms">documentation</a> to learn more. </div> <div class="silex-form__group col2"> <label class="silex-form__element"> <h3>Create pages from data</h3> <p class="silex-help">Pagination allows you to iterate over data and create multiple webiste pages from a single page in Silex. </p> <state-editor id="eleventyPageData" name="eleventyPageData" value=${settings.eleventyPageData ?? ''} .editor=${config.getEditor()} .selected=${body} @change=${() => { showWarningDirty() }} no-states no-filters > <label slot="label">Data</label> </state-editor> <div id="pageination-data-changed" class="silex-warning silex-hidden" > <!-- Reloading silex will make it possible to set the permalink with the latest available data --> <p>\u26A0\uFE0F Pagination data changed. Please click "<strong>apply</strong>" then <strong>reload</strong> Silex.</p> </div> <label class="silex-form__element">Size <input type="number" name="eleventyPageSize" .value=${settings.eleventyPageSize ?? 1}/> </label> <label class="silex-form__element">Reverse <input type="checkbox" name="eleventyPageReverse" ?checked=${!!settings.eleventyPageReverse}/> </label> <state-editor id="eleventyPermalink" name="eleventyPermalink" value=${settings.eleventyPermalink ?? ''} .editor=${config.getEditor()} .selected=${body} > <label slot="label">Permalink</label> </state-editor> <label class="silex-form__element">Available languages <p class="silex-help">Silex can duplicate this page for each language and generate a different URL for each language.</p> <p class="silex-help">Provide a comma separated list of languages. For example: <code>en,fr</code>. An empty value will deactivate this feature.</p> <input type="text" name="silexLanguagesList" .value=${settings.silexLanguagesList ?? ''}/> </label> </label> <label class="silex-form__element"> <h3>Navigation Plugin</h3> <p class="silex-help">This 11ty plugin enables infinite-depth hierarchical navigation in Eleventy projects. Supports breadcrumbs too! <a target="_blank" href="https://www.11ty.dev/docs/plugins/navigation/">Read more about the Navigation Plugin</a>.</p> <label class="silex-form__element">Key <input type="text" name="eleventyNavigationKey" .value=${settings.eleventyNavigationKey ?? ''}/> </label> <label class="silex-form__element">Title <input type="text" name="eleventyNavigationTitle" .value=${settings.eleventyNavigationTitle ?? ''}/> </label> <label class="silex-form__element">Order <input type="number" name="eleventyNavigationOrder" .value=${settings.eleventyNavigationOrder ?? ''}/> </label> <label class="silex-form__element">Parent <input type="text" name="eleventyNavigationParent" .value=${settings.eleventyNavigationParent ?? ''}/> </label> <label class="silex-form__element">URL <input type="text" name="eleventyNavigationUrl" .value=${settings.eleventyNavigationUrl ?? ''}/> </label> </label> <label class="silex-form__element"> <h3>SEO</h3> <state-editor id="eleventySeoTitle" name="eleventySeoTitle" .value=${settings.eleventySeoTitle ?? ''} .editor=${config.getEditor()} .selected=${body} > <label slot="label">Title</label> </state-editor> <state-editor id="eleventySeoDescription" name="eleventySeoDescription" .value=${settings.eleventySeoDescription ?? ''} .editor=${config.getEditor()} .selected=${body} > <label slot="label">Description</label> </state-editor> <state-editor id="eleventyFavicon" name="eleventyFavicon" .value=${settings.eleventyFavicon ?? ''} .editor=${config.getEditor()} .selected=${body} > <label slot="label">Favicon</label> </state-editor> </label> <label class="silex-form__element"> <h3>Social</h3> <state-editor id="eleventyOGImage" name="eleventyOGImage" .value=${settings.eleventyOGImage ?? ''} .editor=${config.getEditor()} .selected=${body} > <label slot="label">OG Image</label> </state-editor> <state-editor id="eleventyOGTitle" name="eleventyOGTitle" .value=${settings.eleventyOGTitle ?? ''} .editor=${config.getEditor()} .selected=${body} > <label slot="label">OG Title</label> </state-editor> <state-editor id="eleventyOGDescription" name="eleventyOGDescription" .value=${settings.eleventyOGDescription ?? ''} .editor=${config.getEditor()} .selected=${body} > <label slot="label">OG Description</label> </state-editor> </div> </div> ` }