Aller au contenu

Configuration de build awesome

Personnalisez le générateur de sites statiques qui construit vos sites web Silex.

Aperçu

Silex utilise build awesome (propulsé par Eleventy) pour compiler les fichiers sources du site web (depuis GrapesJS) en HTML statique, CSS et ressources. Le processus de construction build awesome est déclenché lorsqu'un utilisateur publie, en exécutant le fichier de configuration .eleventy.js et les fichiers de données.

Vous pouvez personnaliser : - La structure des répertoires (input, output, includes) - Les plugins et filtres - Les fichiers de données (.json, .js) - Les langages de templates - Les transformations et passes de construction

Prérequis

Configuration CMS (EleventyPluginOptions)

Le plugin CMS de Silex expose un objet de configuration qui contrôle le comportement de build awesome :

interface EleventyPluginOptions {
  enabled: boolean // Enable/disable 11ty build
  enable11ty: boolean // Actually run 11ty (vs just passing files through)
  cacheBuster: boolean // Add timestamps to asset URLs
  dataSources: DataSource[] // GraphQL APIs for CMS
  dir: {
    input: string // Where website files come from
    html: string // Where HTML files go (relative to input)
    assets: string // Assets directory
    css: string // CSS directory
  }
  urls: {
    css: string // Public URL prefix for CSS
    assets: string // Public URL prefix for assets
  }
}

Configuration dans la config client

Définissez les options CMS dans votre fichier de configuration client :

// client-config.js
export default async function (config) {
  config.cmsConfig = {
    enabled: true,
    enable11ty: true,
    cacheBuster: false,
    dataSources: [
      {
        id: 'wordpress',
        type: 'graphql',
        url: 'https://my-wordpress.com/graphql',
      },
    ],
    dir: {
      input: '',
      html: '',
      assets: 'assets',
      css: 'css',
    },
    urls: {
      css: '/css',
      assets: '/assets',
    },
  }
}

Structure des répertoires

Lors de la publication, Silex crée cette structure :

.
├── .eleventy.js           — 11ty config
├── .eleventyignore        — Files to exclude
├── _data/                 — Global data files
│   ├── site.json          — Site settings
│   └── (CMS data)         — From GraphQL APIs
├── css/                   — Stylesheets
│   ├── page-name.css
│   └── global.css
├── assets/                — Images, fonts, etc.
│   ├── logo.png
│   └── hero.jpg
├── _includes/             — Reusable templates
│   └── page-layout.liquid
├── index.html             — Home page
├── about.html             — Other pages
└── blog/
    ├── index.html         — Collection page
    └── post-1.html        — Generated pages

Personnaliser les répertoires

Changez d'où viennent les entrées et où vont les sorties :

// In your .eleventy.js
module.exports = function(eleventyConfig) {
  return {
    dir: {
      input: 'content',      // Input directory (default: '.')
      output: '_site',       // Output directory (default: '_site')
      includes: '_layouts',  // Includes directory
      layouts: '_layouts',   // Layouts directory
      data: '_data_custom',  // Data files directory
    },
  }
}

Dans la configuration client Silex, l'option dir.input affecte les chemins relatifs :

config.cmsConfig.dir = {
  input: 'src',
  html: 'pages',
  assets: 'static/assets',
  css: 'static/css',
}

Personnaliser la construction

Créez un fichier .eleventy.js à la racine de votre site publié pour étendre la configuration par défaut de Silex :

// .eleventy.js
module.exports = function(eleventyConfig) {
  // Add custom filters
  eleventyConfig.addFilter('uppercase', (value) => {
    return value.toUpperCase()
  })

  // Add a plugin
  const syntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight')
  eleventyConfig.addPlugin(syntaxHighlight)

  // Add a custom collection
  eleventyConfig.addCollection('posts', (collection) => {
    return collection.getFilteredByGlob('posts/*.md').sort((a, b) => {
      return b.date - a.date
    })
  })

  // Passthrough copy (don't process these files)
  eleventyConfig.addPassthroughCopy('fonts/')

  // Return config options
  return {
    pathPrefix: '/',
    htmlTemplateEngine: 'liquid',
  }
}

Fichiers de données

Créez des fichiers .json ou .js dans _data/ pour rendre les données disponibles dans tous les templates :

// _data/site.json
{
  "title": "My Website",
  "description": "A great website",
  "socialImage": "/assets/og-image.jpg"
}

Dans n'importe quel template HTML :

<title>{{ site.title }}</title>
<meta name="description" content="{{ site.description }}">

Fichiers de données dynamiques

Utilisez des fichiers .js pour récupérer des données au moment de la construction :

// _data/posts.js
module.exports = async () => {
  const response = await fetch('https://api.example.com/posts')
  return response.json()
}

Puis utilisez dans les templates :

{% for post in posts %}
  <h2>{{ post.title }}</h2>
{% endfor %}

Données CMS

Lorsque les sources de données Silex sont activées, leurs données sont disponibles dans _data/ :

// Silex fetches from WordPress and makes it available
// _data/wordpress.json (generated)
{
  "posts": [
    { "id": 1, "title": "First Post", "content": "..." },
    { "id": 2, "title": "Second Post", "content": "..." }
  ]
}

Utilisez dans les templates :

{% for post in wordpress.posts %}
  <article>
    <h2>{{ post.title }}</h2>
    <p>{{ post.content }}</p>
  </article>
{% endfor %}

Plugins

Ajoutez des plugins build awesome pour étendre les fonctionnalités :

// .eleventy.js
const syntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight')
const image = require('@11ty/eleventy-img')

module.exports = function(eleventyConfig) {
  // Add a plugin
  eleventyConfig.addPlugin(syntaxHighlight)

  // Add image optimization
  eleventyConfig.addNunjucksAsyncShortcode('image', async (src, alt) => {
    const metadata = await image(src, {
      widths: [300, 600, 1200],
      formats: ['webp', 'jpeg'],
      outputDir: '_site/img/',
    })

    const imageMarkup = Object.values(metadata)
      .map(imageFormat => imageFormat[imageFormat.length - 1])
      .map(image => `<source srcset="${image.srcset}" type="${image.sourceType}">`)
      .join('')

    return `<picture>${imageMarkup}</picture>`
  })

  return {
    dir: {
      input: '.',
      output: '_site',
    },
  }
}

Plugins populaires :

Plugin Rôle
@11ty/eleventy-plugin-syntaxhighlight Coloration syntaxique du code avec Prism
@11ty/eleventy-img Optimisation et images responsives
@11ty/eleventy-plugin-rss Génération de flux RSS
@11ty/eleventy-navigation Gestion des menus de navigation
@11ty/eleventy-plugin-bundle Regroupement des ressources et optimisation inline

Shortcodes

Les shortcodes sont des balises de template personnalisées. Définissez-les dans .eleventy.js :

eleventyConfig.addShortcode('year', () => {
  return new Date().getFullYear()
})

eleventyConfig.addPairedShortcode('callout', (content, type = 'info') => {
  return `<div class="callout callout-${type}">${content}</div>`
})

Utilisez dans les templates :

<footer>
  <p>Copyright &copy; {% year %}</p>
</footer>

{% callout "warning" %}
This is important!
{% endcallout %}

Dans Silex, les éditeurs peuvent insérer des shortcodes via un bloc shortcode.

Filtres

Créez des filtres personnalisés pour transformer les données :

eleventyConfig.addFilter('readableDate', (dateObj) => {
  return new Date(dateObj).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  })
})

eleventyConfig.addFilter('limit', (array, limit) => {
  return array.slice(0, limit)
})

Utilisez dans les templates :

<time>{{ date | readableDate }}</time>

{% for post in posts | limit(5) %}
  <h2>{{ post.title }}</h2>
{% endfor %}

Collections

Créez des collections pour regrouper et trier le contenu :

eleventyConfig.addCollection('posts', (collection) => {
  return collection
    .getFilteredByGlob('posts/**/*.html')
    .sort((a, b) => b.date - a.date)
})

eleventyConfig.addCollection('recent', (collection) => {
  const now = new Date()
  return collection
    .getAll()
    .filter(item => item.date < now)
    .reverse()
    .slice(0, 5)
})

Utilisez dans les templates :

{% for post in collections.posts %}
  <article>{{ post.data.title }}</article>
{% endfor %}

Transformations et passes

Traitez l'ensemble de la sortie HTML pendant la construction :

// Minify HTML in production
if (process.env.NODE_ENV === 'production') {
  eleventyConfig.addTransform('minify', (content) => {
    if (!content.includes('<!doctype html>')) return content

    const minifyHtml = require('minify-html')
    return minifyHtml.minify(Buffer.from(content), {
      do_not_minify_doctype: true,
      minify_css: true,
      minify_js: true,
    }).toString()
  })
}

Cache busting

Activez le cache busting pour ajouter des horodatages aux URL des ressources :

config.cmsConfig.cacheBuster = true

Cela réécrit :

/css/style.css → /css/style.1234567890.css
/assets/logo.png → /assets/logo.1234567890.png

Excellent pour éviter les problèmes de cache du navigateur lors des mises à jour.

Exemple : .eleventy.js complet

// .eleventy.js
const syntaxHighlight = require('@11ty/eleventy-plugin-syntaxhighlight')
const image = require('@11ty/eleventy-img')
const { EleventyHtmlBasePlugin } = require('@11ty/eleventy')

module.exports = function(eleventyConfig) {
  // Plugins
  eleventyConfig.addPlugin(syntaxHighlight)
  eleventyConfig.addPlugin(EleventyHtmlBasePlugin)

  // Filters
  eleventyConfig.addFilter('date', (dateObj) => {
    return new Date(dateObj).toISOString().split('T')[0]
  })

  // Collections
  eleventyConfig.addCollection('sortedPosts', (collection) => {
    return collection
      .getFilteredByGlob('posts/**/*.html')
      .sort((a, b) => b.date - a.date)
  })

  // Shortcodes
  eleventyConfig.addShortcode('year', () => new Date().getFullYear())

  // Transforms
  eleventyConfig.addTransform('minify', (content, outputPath) => {
    if (outputPath && outputPath.endsWith('.html')) {
      const minify = require('html-minifier')
      return minify.minify(content, { useShortDoctype: true })
    }
    return content
  })

  // Passthrough
  eleventyConfig.addPassthroughCopy('fonts/')
  eleventyConfig.addPassthroughCopy('vendor/')

  return {
    dir: {
      input: '.',
      output: '_site',
      includes: '_includes',
      data: '_data',
    },
    htmlTemplateEngine: 'liquid',
    pathPrefix: '/',
  }
}

Dépannage

La construction est trop lente

Build awesome peut être lent si : - Il récupère des données depuis des API externes à chaque construction - Il traite de nombreuses images volumineuses - Les filtres ou transformations sont complexes

Optimisez :

  1. Mettez en cache les fichiers de données entre les constructions
  2. Utilisez un CDN pour les images au lieu du traitement local
  3. Simplifiez les filtres ou déplacez la logique côté client

Les données ne sont pas disponibles dans les templates

Vérifiez : - Le fichier est dans le répertoire _data/ - Le nom du fichier correspond au nom de la variable (par ex. site.json{{ site }}) - Pas d'erreurs de syntaxe dans les fichiers .js - Le journal de build awesome affiche "Writing X files"

Les shortcodes ne fonctionnent pas

Assurez-vous : - Définis dans .eleventy.js avant de retourner la configuration - Utilisés avec la syntaxe correcte (appairés vs non appairés) - Le fichier est à la racine du site publié (pas dans node_modules)

Voir aussi

Éditer cette page sur GitLab