refactor: add sass, minify HTML, remove i18n

feat/integration_ideo
Nicolas Doby 2022-10-20 16:10:47 +02:00
parent d211e28aa5
commit 8c0034d325
40 changed files with 405 additions and 197 deletions

2
.gitignore vendored
View File

@ -1,5 +1,7 @@
.idea .idea
*iml *iml
_site/ _site/
dist/
node_modules/ node_modules/
package-lock.json package-lock.json
src/compiled-assets

View File

@ -73,8 +73,8 @@ DEBUG=Eleventy* npx @11ty/eleventy
- The `public` folder in your input directory will be copied to the output folder (via `addPassthroughCopy()` in the `.eleventy.js` file). This means `./public/css/*` will live at `./_site/css/*` after your build completes. [When using `--serve` this behavior is emulated](/docs/copy/#passthrough-during-serve) (the files will not show up in `_site`). - The `public` folder in your input directory will be copied to the output folder (via `addPassthroughCopy()` in the `.eleventy.js` file). This means `./public/css/*` will live at `./_site/css/*` after your build completes. [When using `--serve` this behavior is emulated](/docs/copy/#passthrough-during-serve) (the files will not show up in `_site`).
- The blog post feed template is in `feed/feed.njk`. This is also a good example of using a global data files in that it uses `_data/metadata.json`. - The blog post feed template is in `feed/feed.njk`. This is also a good example of using a global data files in that it uses `_data/metadata.json`.
- This project uses three layouts: - This project uses three layouts:
- `_includes/layouts/base.njk`: the top level HTML structure - `_layouts/base.njk`: the top level HTML structure
- `_includes/layouts/home.njk`: the home page template (wrapped into `base.njk`) - `_layouts/home.njk`: the home page template (wrapped into `base.njk`)
- `_includes/layouts/post.njk`: the blog post template (wrapped into `base.njk`) - `_layouts/post.njk`: the blog post template (wrapped into `base.njk`)
- `_includes/postslist.njk` is a Nunjucks include and is a reusable component used to display a list of all the posts. `index.njk` has an example of how to use it. - `_components/postslist.njk` is a Nunjucks include and is a reusable component used to display a list of all the posts. `index.njk` has an example of how to use it.

View File

@ -1,14 +1,12 @@
const fs = require("fs");
const path = require("path");
const { DateTime } = require("luxon"); const { DateTime } = require("luxon");
const rosetta = require("rosetta");
const markdownItAnchor = require("markdown-it-anchor"); const markdownItAnchor = require("markdown-it-anchor");
const pluginRss = require("@11ty/eleventy-plugin-rss"); const pluginRss = require("@11ty/eleventy-plugin-rss");
const pluginSyntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight"); const pluginSyntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
const pluginNavigation = require("@11ty/eleventy-navigation"); const pluginNavigation = require("@11ty/eleventy-navigation");
const { EleventyI18nPlugin, EleventyHtmlBasePlugin } = require("@11ty/eleventy"); const { EleventyHtmlBasePlugin } = require("@11ty/eleventy");
const languageStrings = require("./i18n.js");
let markdownIt = require("markdown-it"); let markdownIt = require("markdown-it");
const htmlmin = require('html-minifier');
let options = { let options = {
// whatever options you have set for the library here // whatever options you have set for the library here
}; };
@ -18,48 +16,28 @@ let figoptions = {
}; };
const mdLib = markdownIt(options).use(mdfigcaption, figoptions); const mdLib = markdownIt(options).use(mdfigcaption, figoptions);
const manifestPath = path.resolve(__dirname, "_site", "assets", "manifest.json");
const manifest = JSON.parse(
fs.readFileSync(manifestPath, { encoding: "utf8" })
);
module.exports = function(eleventyConfig) { module.exports = function(eleventyConfig) {
eleventyConfig.ignores.add("README.md"); eleventyConfig.setUseGitIgnore(false);
eleventyConfig.setLibrary("md", mdLib); eleventyConfig.setLibrary("md", mdLib);
// Adds a universal shortcode to return the URL to a webpack asset. In Nunjack templates: // Watch our compiled assets for changes
// {% webpackAsset 'main.js' %} or {% webpackAsset 'main.css' %} eleventyConfig.addWatchTarget('./src/compiled-assets/main.css');
eleventyConfig.addShortcode("webpackAsset", function(name) { //eleventyConfig.addWatchTarget('./src/compiled-assets/main.js');
if (!manifest[name]) { //eleventyConfig.addWatchTarget('./src/compiled-assets/vendor.js');
throw new Error(`The asset ${name} does not exist in ${manifestPath}`);
}
return manifest[name];
});
// Copy all images directly to dist. // Copy src/compiled-assets to /assets
eleventyConfig.addPassthroughCopy({ "public/img": "img" }); eleventyConfig.addPassthroughCopy({ 'src/compiled-assets': 'assets' });
// Copy all images
eleventyConfig.addPassthroughCopy('src/images');
// Copy the contents of the `public` folder to the output folder // Add plugins
// For example, `./public/css/` ends up in `_site/css/`
// eleventyConfig.addPassthroughCopy({
// "./node_modules/prismjs/themes/prism-okaidia.css": "/public/css/prism-theme.css",
// });
// // Watch our compiled assets for changes
// eleventyConfig.addWatchTarget('./src/compiled-assets/main.css');
// // Copy src/compiled-assets to /assets
// eleventyConfig.addPassthroughCopy({ 'src/compiled-assets': 'assets' });
// Add plugins
eleventyConfig.addPlugin(pluginRss); eleventyConfig.addPlugin(pluginRss);
eleventyConfig.addPlugin(pluginSyntaxHighlight); eleventyConfig.addPlugin(pluginSyntaxHighlight);
eleventyConfig.addPlugin(pluginNavigation); eleventyConfig.addPlugin(pluginNavigation);
eleventyConfig.addPlugin(EleventyHtmlBasePlugin); eleventyConfig.addPlugin(EleventyHtmlBasePlugin);
eleventyConfig.addPlugin(EleventyI18nPlugin, { eleventyConfig.addFilter("env", (key, def="NOT DEFINED") => process.env[key] || def);
defaultLanguage: "fr",
errorMode: "allow-fallback",
});
eleventyConfig.addFilter("readableDate", (dateObj, format = "dd LLLL yyyy") => { eleventyConfig.addFilter("readableDate", (dateObj, format = "dd LLLL yyyy") => {
return DateTime.fromJSDate(dateObj, {zone: 'utc', locale: 'fr'}).toFormat(format); return DateTime.fromJSDate(dateObj, {zone: 'utc', locale: 'fr'}).toFormat(format);
@ -115,23 +93,26 @@ module.exports = function(eleventyConfig) {
}); });
}); });
// Override @11ty/eleventy-dev-server defaults (used only with --serve) // Override @11ty/eleventy-dev-server defaults (used only with --serve)
eleventyConfig.setServerOptions({ eleventyConfig.setServerOptions({
showVersion: true, showVersion: true,
}); });
// i18n filter using Rosetta if (process.env.ELEVENTY_ENV === 'production') {
const rosettaLib = rosetta(languageStrings); eleventyConfig.addTransform('htmlmin', (content, outputPath) => {
if (outputPath.endsWith('.html')) {
return htmlmin.minify(content, {
collapseInlineTagWhitespace: false,
collapseWhitespace: true,
removeComments: true,
sortClassName: true,
useShortDoctype: true,
});
}
eleventyConfig.addFilter("i18n", function (key, lang) { return content;
const I18N_PREFIX = "i18n."; });
if(key.startsWith(I18N_PREFIX)) { }
key = key.slice(I18N_PREFIX.length);
}
// depends on page.lang in 2.0.0-canary.14+
let page = this.page || this.ctx?.page || this.context?.environments?.page || {};
return rosettaLib.t(key, {}, lang || page.lang);
});
return { return {
// Control which files Eleventy will process // Control which files Eleventy will process
@ -165,10 +146,185 @@ module.exports = function(eleventyConfig) {
// These are all optional (defaults are shown): // These are all optional (defaults are shown):
dir: { dir: {
input: ".", input: 'src',
includes: "_includes", includes: '_components',
data: "_data", layouts: '_layouts',
output: "_site" output: 'dist',
} },
}; };
}; };
// const fs = require("fs");
// const path = require("path");
// const { DateTime } = require("luxon");
// const rosetta = require("rosetta");
// const markdownItAnchor = require("markdown-it-anchor");
// const pluginRss = require("@11ty/eleventy-plugin-rss");
// const pluginSyntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight");
// const pluginNavigation = require("@11ty/eleventy-navigation");
// const { EleventyI18nPlugin, EleventyHtmlBasePlugin } = require("@11ty/eleventy");
// const languageStrings = require("./i18n.js");
// let markdownIt = require("markdown-it");
// let options = {
// // whatever options you have set for the library here
// };
// let mdfigcaption = require('markdown-it-image-figures');
// let figoptions = {
// figcaption: true
// };
// const mdLib = markdownIt(options).use(mdfigcaption, figoptions);
//
// const manifestPath = path.resolve(__dirname, "_site", "assets", "manifest.json");
// const manifest = JSON.parse(
// fs.readFileSync(manifestPath, { encoding: "utf8" })
// );
//
// module.exports = function(eleventyConfig) {
// eleventyConfig.ignores.add("README.md");
//
// eleventyConfig.setLibrary("md", mdLib);
//
// // Adds a universal shortcode to return the URL to a webpack asset. In Nunjack templates:
// // {% webpackAsset 'main.js' %} or {% webpackAsset 'main.css' %}
// eleventyConfig.addShortcode("webpackAsset", function(name) {
// if (!manifest[name]) {
// throw new Error(`The asset ${name} does not exist in ${manifestPath}`);
// }
// return manifest[name];
// });
//
// // Copy all images directly to dist.
// eleventyConfig.addPassthroughCopy({ "public/img": "img" });
//
// // Copy the contents of the `public` folder to the output folder
// // For example, `./public/css/` ends up in `_site/css/`
// // eleventyConfig.addPassthroughCopy({
// // "./node_modules/prismjs/themes/prism-okaidia.css": "/public/css/prism-theme.css",
// // });
// // // Watch our compiled assets for changes
// // eleventyConfig.addWatchTarget('./src/compiled-assets/main.css');
// // // Copy src/compiled-assets to /assets
// // eleventyConfig.addPassthroughCopy({ 'src/compiled-assets': 'assets' });
//
// // Add plugins
// eleventyConfig.addPlugin(pluginRss);
// eleventyConfig.addPlugin(pluginSyntaxHighlight);
// eleventyConfig.addPlugin(pluginNavigation);
// eleventyConfig.addPlugin(EleventyHtmlBasePlugin);
//
// eleventyConfig.addPlugin(EleventyI18nPlugin, {
// defaultLanguage: "fr",
// errorMode: "allow-fallback",
// });
//
// eleventyConfig.addFilter("readableDate", (dateObj, format = "dd LLLL yyyy") => {
// return DateTime.fromJSDate(dateObj, {zone: 'utc', locale: 'fr'}).toFormat(format);
// });
//
// // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string
// eleventyConfig.addFilter('htmlDateString', (dateObj) => {
// return DateTime.fromJSDate(dateObj, {zone: 'utc', locale: 'fr'}).toFormat('yyyy-LL-dd');
// });
//
// // Get the first `n` elements of a collection.
// eleventyConfig.addFilter("head", (array, n) => {
// if(!Array.isArray(array) || array.length === 0) {
// return [];
// }
// if( n < 0 ) {
// return array.slice(n);
// }
//
// return array.slice(0, n);
// });
//
// // Return the smallest number argument
// eleventyConfig.addFilter("min", (...numbers) => {
// return Math.min.apply(null, numbers);
// });
//
// // Return all the tags used in a collection
// eleventyConfig.addFilter("getAllTags", collection => {
// let tagSet = new Set();
// for(let item of collection) {
// (item.data.tags || []).forEach(tag => tagSet.add(tag));
// }
// return Array.from(tagSet).sort((a, b) => {
// return a.localeCompare(b, undefined, {sensitivity: 'base'});
// });
// });
//
// eleventyConfig.addFilter("filterTagList", function filterTagList(tags) {
// return (tags || []).filter(tag => ["all", "nav", "post", "posts"].indexOf(tag) === -1);
// });
//
// // Customize Markdown library and settings:
// eleventyConfig.amendLibrary("md", mdLib => {
// mdLib.use(markdownItAnchor, {
// permalink: markdownItAnchor.permalink.ariaHidden({
// placement: "after",
// class: "direct-link",
// symbol: "#",
// }),
// level: [1,2,3,4],
// slugify: eleventyConfig.getFilter("slug")
// });
// });
//
// // Override @11ty/eleventy-dev-server defaults (used only with --serve)
// eleventyConfig.setServerOptions({
// showVersion: true,
// });
//
// // i18n filter using Rosetta
// const rosettaLib = rosetta(languageStrings);
//
// eleventyConfig.addFilter("i18n", function (key, lang) {
// const I18N_PREFIX = "i18n.";
// if(key.startsWith(I18N_PREFIX)) {
// key = key.slice(I18N_PREFIX.length);
// }
// // depends on page.lang in 2.0.0-canary.14+
// let page = this.page || this.ctx?.page || this.context?.environments?.page || {};
// return rosettaLib.t(key, {}, lang || page.lang);
// });
//
// return {
// // Control which files Eleventy will process
// // e.g.: *.md, *.njk, *.html, *.liquid
// templateFormats: [
// "md",
// "njk",
// "html",
// "liquid"
// ],
//
// // Pre-process *.md files with: (default: `liquid`)
// markdownTemplateEngine: "njk",
//
// // Pre-process *.html files with: (default: `liquid`)
// htmlTemplateEngine: "njk",
//
// // -----------------------------------------------------------------
// // If your site deploys to a subdirectory, change `pathPrefix`.
// // Dont worry about leading and trailing slashes, we normalize these.
//
// // If you dont have a subdirectory, use "" or "/" (they do the same thing)
// // This is only used for link URLs (it does not affect your file structure)
// // Best paired with the `url` filter: https://www.11ty.dev/docs/filters/url/
//
// // You can also pass this in on the command line using `--pathprefix`
//
// // Optional (default is shown)
// pathPrefix: "/",
// // -----------------------------------------------------------------
//
// // These are all optional (defaults are shown):
// dir: {
// input: ".",
// includes: "_includes",
// data: "_data",
// output: "_site"
// }
// };
// };

View File

@ -1,11 +0,0 @@
module.exports = {
lang: "fr",
permalink: function(data) {
// Change (Francais) /fr/blog/my-post URLs to have an implied language code /blog/my-post URLs instead.
let [slashPrefixEmpty, langCode, ...stem] = data.page.filePathStem.split("/");
let path = stem.join("/");
// Account for `permalink: 404.html` style
return stem[stem.length - 1] === "index" ? `${path}.html` : `${path}/index.html`;
}
}

View File

@ -3,38 +3,52 @@
"version": "1.0.0", "version": "1.0.0",
"description": "Blog IT's on us", "description": "Blog IT's on us",
"scripts": { "scripts": {
"build": "npm-run-all clean build:assets build:site", "build:assets": "webpack --config webpack.config.prod.js",
"build:assets": "NODE_ENV=production webpack --mode=production", "build:site": "ELEVENTY_ENV=production npx eleventy",
"build:site": "NODE_ENV=production eleventy", "del:assets": "rimraf ./src/compiled-assets",
"clean": "rm -rf ./_site", "del:dist": "rimraf ./dist",
"dev": "npm-run-all clean webpack:assets --parallel dev:*", "dev": "npm run dev:assets & npm run dev:site",
"dev:assets": "npm run webpack:assets --watch", "dev:assets": "webpack --config webpack.config.dev.js",
"dev:site": "NODE_ENV=development eleventy --serve", "dev:site": "ELEVENTY_ENV=development npx eleventy --serve",
"webpack:assets": "NODE_ENV=development webpack --mode=development" "prod": "npm-run-all del:dist del:assets build:assets build:site",
"serve:prod": "serve ./dist/"
},
"repository": {
"type": "git",
"url": "https://git.itsonus.fr/internal/itsonus-blog"
}, },
"dependencies": { "dependencies": {
"@11ty/eleventy": "^2.0.0-canary.16", "@11ty/eleventy": "^2.0.0-canary.16",
"@11ty/eleventy-navigation": "^0.3.5", "@11ty/eleventy-navigation": "^0.3.5",
"@11ty/eleventy-plugin-rss": "^1.2.0", "@11ty/eleventy-plugin-rss": "^1.2.0",
"@11ty/eleventy-plugin-syntaxhighlight": "^4.1.0", "@11ty/eleventy-plugin-syntaxhighlight": "^4.1.0",
"@babel/core": "^7.10.2",
"@babel/preset-env": "^7.10.2",
"autoprefixer": "^9.8.0",
"babel-loader": "^8.1.0",
"css-loader": "^3.5.3",
"cssnano": "^4.1.10",
"luxon": "^3.0.1",
"markdown-it-anchor": "^8.6.4", "markdown-it-anchor": "^8.6.4",
"markdown-it-image-figures": "^2.1.0", "markdown-it-image-figures": "^2.1.0",
"mini-css-extract-plugin": "^0.9.0", "luxon": "^3.0.4",
"@babel/core": "^7.18.2",
"@babel/preset-env": "^7.18.2",
"autoprefixer": "^10.4.7",
"babel-loader": "^8.2.5",
"core-js": "^3.22.8",
"css-loader": "^6.7.1",
"eslint": "^8.17.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-plugin-import": "^2.26.0",
"html-minifier": "^4.0.0",
"md5-file": "^5.0.0",
"mini-css-extract-plugin": "^2.6.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"postcss-import": "^12.0.1", "css-minimizer-webpack-plugin": "^4.0.0",
"postcss-loader": "^3.0.0", "postcss-loader": "^7.0.0",
"postcss-preset-env": "^6.7.0", "rimraf": "^3.0.2",
"rosetta": "^1.1.0", "sass": "^1.52.2",
"webpack": "^4.43.0", "sass-loader": "^13.0.0",
"webpack-cli": "^3.3.11", "serve": "^13.0.2",
"webpack-manifest-plugin": "^2.2.0" "terser-webpack-plugin": "^5.3.3",
"webpack": "^5.73.0",
"webpack-cli": "^4.9.2",
"webpack-merge": "^5.8.0"
}, },
"devDependencies": { "devDependencies": {
"prettier": "^2.0.5" "prettier": "^2.0.5"

View File

@ -1,10 +1,6 @@
const plugins = [ module.exports = {
require("postcss-import"), plugins: [
require("postcss-preset-env"), // eslint-disable-next-line global-require
]; require('autoprefixer'),
],
if (process.env.NODE_ENV === "production") { };
plugins.push(require("cssnano"));
}
module.exports = { plugins };

View File

@ -1 +0,0 @@
// console.log("Elevenpack javascript is loaded");

View File

@ -2,8 +2,6 @@
<ul class="links"> <ul class="links">
{%- for entry in collections.all | eleventyNavigation %} {%- for entry in collections.all | eleventyNavigation %}
<li><a <li><a
href="{{ entry.url }}">{{ entry.title | i18n }}</a></li> href="{{ entry.url }}">{{ entry.title }}</a></li>
{%- endfor %} {%- endfor %}
<li><a
href="https://www.itsonus.fr" target="_blank">IT's on us</a></li>
</ul> </ul>

21
src/_data/cacheBust.js Normal file
View File

@ -0,0 +1,21 @@
const md5File = require('md5-file');
const cacheBust = () => {
// A "map" of files to cache bust
const files = {
mainCss: './src/compiled-assets/main.css',
// mainJs: './src/compiled-assets/main.js',
// vendorJs: './src/compiled-assets/vendor.js',
};
return Object.entries(files).reduce((acc, [key, path]) => {
const now = Date.now();
const bust = process.env.ELEVENTY_ENV === 'production' ? md5File.sync(path, (_err, hash) => hash) : now;
acc[key] = bust;
return acc;
}, {});
};
module.exports = cacheBust;

View File

@ -1,29 +1,21 @@
<!doctype html> <!doctype html>
<html lang="{{ lang or metadata.language }}"> <html lang="{{ metadata.language }}">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title or metadata.title }}</title> <title>{{ title or metadata.title }}</title>
<meta name="description" content="{{ description or metadata.description }}"> <meta name="description" content="{{ description or metadata.description }}">
<meta name="generator" content="{{ eleventy.generator }}"> <meta name="generator" content="{{ eleventy.generator }}">
<link rel="stylesheet" href="{% webpackAsset 'main.css' %}"> <link rel="stylesheet" href="/assets/main.css?{{ cacheBust.mainCss }}"/>
<link rel="alternate" href="/feed/feed.xml" type="application/atom+xml" title="{{ metadata.title }}"> <link rel="alternate" href="/feed/feed.xml" type="application/atom+xml" title="{{ metadata.title }}">
<link rel="alternate" href="/feed/feed.json" type="application/json" title="{{ metadata.title }}"> <link rel="alternate" href="/feed/feed.json" type="application/json" title="{{ metadata.title }}">
<link rel="icon" href="/img/favicon.svg"> <link rel="icon" href="/images/favicon.svg">
{%- set alternateUrls = page.url | locale_links %}
{% if alternateUrls.length %}
<link rel="alternate" hreflang="{{ lang or metadata.language }}" href="{{ page.url | htmlBaseUrl(metadata.url) }}">
{%- for link in alternateUrls %}
<link rel="alternate" hreflang="{{ link.lang }}" href="{{ link.url | htmlBaseUrl(metadata.url) }}">
{%- endfor %}
{%- endif %}
</head> </head>
<body class="container"> <body class="container">
<header class="main-header"> <header class="main-header">
<div> <div>
<a class="main-header-logo" href="/"> <a class="main-header-logo" href="/">
<img src="/img/logo.svg" alt="IT's on us" width="165" height="33"> <img src="/images/logo.svg" alt="IT's on us" width="165" height="33">
Blog Blog
</a> </a>
</div> </div>
@ -53,7 +45,7 @@
</a> </a>
</li> </li>
<li> <li>
<a href="/feed/feed.xml" download> <a href="/src/_pages/feed/feed.xml" download>
<svg width="32" height="32" viewBox="0 0 461.432 461.432" xmlns="http://www.w3.org/2000/svg" aria-labelledby="title-rss"><title id="title-rss">Accéder au flux RSS du blog</title><g fill="#fff"><path d="M125.896 398.928c0 33.683-27.308 60.999-61.022 60.999-33.684 0-61.006-27.316-61.006-60.999 0-33.729 27.322-61.038 61.006-61.038 33.714 0 61.022 27.308 61.022 61.038zM0 229.636c0 8.441 6.606 15.379 15.036 15.809 60.318 3.076 100.885 25.031 138.248 62.582 36.716 36.864 60.071 89.759 64.082 137.769.686 8.202 7.539 14.524 15.77 14.524h56.701c4.344 0 8.498-1.784 11.488-4.935a15.852 15.852 0 004.333-11.729c-8.074-158.152-130.669-278.332-289.013-286.23a15.846 15.846 0 00-11.709 4.344A15.848 15.848 0 000 173.247v56.389z"/><path d="M0 73.411c0 8.51 6.713 15.482 15.216 15.819 194.21 7.683 350.315 161.798 358.098 355.879.34 8.491 7.32 15.208 15.818 15.208h56.457c4.297 0 8.408-1.744 11.393-4.834a15.857 15.857 0 004.441-11.552C453.181 199.412 261.024 9.27 16.38 1.121A15.844 15.844 0 004.838 5.568 15.842 15.842 0 000 16.954v56.457z"/></g> <svg width="32" height="32" viewBox="0 0 461.432 461.432" xmlns="http://www.w3.org/2000/svg" aria-labelledby="title-rss"><title id="title-rss">Accéder au flux RSS du blog</title><g fill="#fff"><path d="M125.896 398.928c0 33.683-27.308 60.999-61.022 60.999-33.684 0-61.006-27.316-61.006-60.999 0-33.729 27.322-61.038 61.006-61.038 33.714 0 61.022 27.308 61.022 61.038zM0 229.636c0 8.441 6.606 15.379 15.036 15.809 60.318 3.076 100.885 25.031 138.248 62.582 36.716 36.864 60.071 89.759 64.082 137.769.686 8.202 7.539 14.524 15.77 14.524h56.701c4.344 0 8.498-1.784 11.488-4.935a15.852 15.852 0 004.333-11.729c-8.074-158.152-130.669-278.332-289.013-286.23a15.846 15.846 0 00-11.709 4.344A15.848 15.848 0 000 173.247v56.389z"/><path d="M0 73.411c0 8.51 6.713 15.482 15.216 15.819 194.21 7.683 350.315 161.798 358.098 355.879.34 8.491 7.32 15.208 15.818 15.208h56.457c4.297 0 8.408-1.744 11.393-4.834a15.857 15.857 0 004.441-11.552C453.181 199.412 261.024 9.27 16.38 1.121A15.844 15.844 0 004.838 5.568 15.842 15.842 0 000 16.954v56.457z"/></g>
</svg> </svg>
</a> </a>

View File

@ -1,5 +1,5 @@
--- ---
layout: layouts/base.njk layout: base.njk
templateClass: tmpl-home templateClass: tmpl-home
--- ---
{{ content | safe }} {{ content | safe }}

View File

@ -1,5 +1,5 @@
--- ---
layout: layouts/base.njk layout: base.njk
templateClass: tmpl-post templateClass: tmpl-post
--- ---
<h1>{{ title }}</h1> <h1>{{ title }}</h1>
@ -16,19 +16,6 @@ templateClass: tmpl-post
<hr> <hr>
{% set i18nLinks = page.url | locale_links %}
{% if i18nLinks.length %}
<ul>
<li>
{{ "i18n.also" | i18n }}
{%- for link in i18nLinks %}
<a href="{{ link.url }}" lang="{{ link.lang }}" hreflang="{{ link.lang }}">{{ link.label }}</a>
{%- if not loop.last %},{% endif %}
{%- endfor -%}
</li>
</ul>
{% endif %}
{%- if collections.posts %} {%- if collections.posts %}
{# these filters are locale-aware in 2.0.0-canary.14 #} {# these filters are locale-aware in 2.0.0-canary.14 #}
{%- set previousPost = collections.posts | getPreviousCollectionItem %} {%- set previousPost = collections.posts | getPreviousCollectionItem %}
@ -36,8 +23,8 @@ templateClass: tmpl-post
{%- if nextPost or previousPost %} {%- if nextPost or previousPost %}
<nav class="post-nav"> <nav class="post-nav">
<ul> <ul>
{%- if previousPost %}<li class="previous">{{ "i18n.previous" | i18n }}: <a href="{{ previousPost.url }}">{{ previousPost.data.title }}</a></li>{% endif %} {%- if previousPost %}<li class="previous">Précédent : <a href="{{ previousPost.url }}">{{ previousPost.data.title }}</a></li>{% endif %}
{%- if nextPost %}<li class="next">{{ "i18n.next" | i18n }}: <a href="{{ nextPost.url }}">{{ nextPost.data.title }}</a></li>{% endif %} {%- if nextPost %}<li class="next">Suivant : <a href="{{ nextPost.url }}">{{ nextPost.data.title }}</a></li>{% endif %}
</ul> </ul>
</nav> </nav>
{%- endif %} {%- endif %}

View File

@ -1,5 +1,5 @@
--- ---
layout: layouts/home.njk layout: home.njk
permalink: 404.html permalink: 404.html
eleventyExcludeFromCollections: true eleventyExcludeFromCollections: true
--- ---

3
src/_pages/_pages.json Normal file
View File

@ -0,0 +1,3 @@
{
"permalink": "{{ page.filePathStem.replace('/_pages', '').replace('/index', '') }}/index.html"
}

View File

@ -1,7 +1,7 @@
--- ---
layout: layouts/home.njk layout: home.njk
eleventyNavigation: eleventyNavigation:
key: nav.all key: Tous les articles
order: 3 order: 3
--- ---
<ul class="post-list"> <ul class="post-list">

View File

@ -1,7 +1,7 @@
--- ---
layout: layouts/home.njk layout: home.njk
eleventyNavigation: eleventyNavigation:
key: nav.archive key: Archives
order: 2 order: 2
--- ---
<h1>Archive</h1> <h1>Archive</h1>

View File

@ -7,14 +7,14 @@ tags:
- ACV - ACV
- EFC - EFC
- écoconception - écoconception
layout: layouts/post.njk layout: post.njk
--- ---
## Introduction ## Introduction
Leverage agile Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Semper quis lectus nulla at volutpat. Est pellentesque elit ullamcorper dignissim cras tincidunt lobortis feugiat. Duis tristique sollicitudin nibh sit amet commodo nulla facilisi. Enim diam vulputate ut pharetra sit amet. Placerat orci nulla pellentesque dignissim. Gravida rutrum quisque non tellus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Diam sollicitudin tempor id eu nisl nunc mi ipsum faucibus. Tempor id eu nisl nunc mi. Cras pulvinar mattis nunc sed blandit libero volutpat sed cras. Eget magna fermentum iaculis eu non diam phasellus. Est lorem ipsum dolor sit amet consectetur adipiscing. Orci porta non pulvinar neque laoreet suspendisse interdum consectetur. Velit scelerisque in dictum non consectetur a. Lectus sit amet est placerat. Viverra aliquet eget sit amet tellus cras adipiscing enim eu. Ut tristique et egestas quis ipsum suspendisse ultrices. Bibendum est ultricies integer quis auctor elit. Aliquam sem et tortor consequat id porta nibh. Leverage agile Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Semper quis lectus nulla at volutpat. Est pellentesque elit ullamcorper dignissim cras tincidunt lobortis feugiat. Duis tristique sollicitudin nibh sit amet commodo nulla facilisi. Enim diam vulputate ut pharetra sit amet. Placerat orci nulla pellentesque dignissim. Gravida rutrum quisque non tellus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Diam sollicitudin tempor id eu nisl nunc mi ipsum faucibus. Tempor id eu nisl nunc mi. Cras pulvinar mattis nunc sed blandit libero volutpat sed cras. Eget magna fermentum iaculis eu non diam phasellus. Est lorem ipsum dolor sit amet consectetur adipiscing. Orci porta non pulvinar neque laoreet suspendisse interdum consectetur. Velit scelerisque in dictum non consectetur a. Lectus sit amet est placerat. Viverra aliquet eget sit amet tellus cras adipiscing enim eu. Ut tristique et egestas quis ipsum suspendisse ultrices. Bibendum est ultricies integer quis auctor elit. Aliquam sem et tortor consequat id porta nibh.
to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy foster collaborative thinking to further the overall value proposition. Organically grow the holistic world view of disruptive innovation via workplace diversity and empowerment. to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy foster collaborative thinking to further the overall value proposition. Organically grow the holistic world view of disruptive innovation via workplace diversity and empowerment.
![Un chaton](/img/blog/kitty_1.jpeg "Un chaton tout mignon 😍") ![Un chaton](/images/blog/kitty_1.jpeg "Un chaton tout mignon 😍")
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Semper quis lectus nulla at volutpat. Est pellentesque elit ullamcorper dignissim cras tincidunt lobortis feugiat. Duis tristique sollicitudin nibh sit amet commodo nulla facilisi. Enim diam vulputate ut pharetra sit amet. Placerat orci nulla pellentesque dignissim. Gravida rutrum quisque non tellus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Diam sollicitudin tempor id eu nisl nunc mi ipsum faucibus. Tempor id eu nisl nunc mi. Cras pulvinar mattis nunc sed blandit libero volutpat sed cras. Eget magna fermentum iaculis eu non diam phasellus. Est lorem ipsum dolor sit amet consectetur adipiscing. Orci porta non pulvinar neque laoreet suspendisse interdum consectetur. Velit scelerisque in dictum non consectetur a. Lectus sit amet est placerat. Viverra aliquet eget sit amet tellus cras adipiscing enim eu. Ut tristique et egestas quis ipsum suspendisse ultrices. Bibendum est ultricies integer quis auctor elit. Aliquam sem et tortor consequat id porta nibh. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Semper quis lectus nulla at volutpat. Est pellentesque elit ullamcorper dignissim cras tincidunt lobortis feugiat. Duis tristique sollicitudin nibh sit amet commodo nulla facilisi. Enim diam vulputate ut pharetra sit amet. Placerat orci nulla pellentesque dignissim. Gravida rutrum quisque non tellus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Diam sollicitudin tempor id eu nisl nunc mi ipsum faucibus. Tempor id eu nisl nunc mi. Cras pulvinar mattis nunc sed blandit libero volutpat sed cras. Eget magna fermentum iaculis eu non diam phasellus. Est lorem ipsum dolor sit amet consectetur adipiscing. Orci porta non pulvinar neque laoreet suspendisse interdum consectetur. Velit scelerisque in dictum non consectetur a. Lectus sit amet est placerat. Viverra aliquet eget sit amet tellus cras adipiscing enim eu. Ut tristique et egestas quis ipsum suspendisse ultrices. Bibendum est ultricies integer quis auctor elit. Aliquam sem et tortor consequat id porta nibh.

View File

@ -6,7 +6,7 @@ date: 2022-10-15
tags: tags:
- accessibilité - accessibilité
- écoconception - écoconception
layout: layouts/post.njk layout: post.njk
--- ---
## Introduction ## Introduction
@ -48,6 +48,6 @@ console.log('Test');
## Conclusion ## Conclusion
![Un chaton](/img/blog/kitty_2.jpeg) ![Un chaton](/images/blog/kitty_2.jpeg)
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Semper quis lectus nulla at volutpat. Est pellentesque elit ullamcorper dignissim cras tincidunt lobortis feugiat. Duis tristique sollicitudin nibh sit amet commodo nulla facilisi. Enim diam vulputate ut pharetra sit amet. Placerat orci nulla pellentesque dignissim. Gravida rutrum quisque non tellus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Diam sollicitudin tempor id eu nisl nunc mi ipsum faucibus. Tempor id eu nisl nunc mi. Cras pulvinar mattis nunc sed blandit libero volutpat sed cras. Eget magna fermentum iaculis eu non diam phasellus. Est lorem ipsum dolor sit amet consectetur adipiscing. Orci porta non pulvinar neque laoreet suspendisse interdum consectetur. Velit scelerisque in dictum non consectetur a. Lectus sit amet est placerat. Viverra aliquet eget sit amet tellus cras adipiscing enim eu. Ut tristique et egestas quis ipsum suspendisse ultrices. Bibendum est ultricies integer quis auctor elit. Aliquam sem et tortor consequat id porta nibh. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Semper quis lectus nulla at volutpat. Est pellentesque elit ullamcorper dignissim cras tincidunt lobortis feugiat. Duis tristique sollicitudin nibh sit amet commodo nulla facilisi. Enim diam vulputate ut pharetra sit amet. Placerat orci nulla pellentesque dignissim. Gravida rutrum quisque non tellus. Condimentum mattis pellentesque id nibh tortor id aliquet lectus proin. Diam sollicitudin tempor id eu nisl nunc mi ipsum faucibus. Tempor id eu nisl nunc mi. Cras pulvinar mattis nunc sed blandit libero volutpat sed cras. Eget magna fermentum iaculis eu non diam phasellus. Est lorem ipsum dolor sit amet consectetur adipiscing. Orci porta non pulvinar neque laoreet suspendisse interdum consectetur. Velit scelerisque in dictum non consectetur a. Lectus sit amet est placerat. Viverra aliquet eget sit amet tellus cras adipiscing enim eu. Ut tristique et egestas quis ipsum suspendisse ultrices. Bibendum est ultricies integer quis auctor elit. Aliquam sem et tortor consequat id porta nibh.

View File

@ -5,7 +5,7 @@ resume: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
date: 2022-10-17 date: 2022-10-17
tags: tags:
- écoconception - écoconception
layout: layouts/post.njk layout: post.njk
--- ---
## Introduction ## Introduction

View File

@ -1,7 +1,7 @@
--- ---
layout: layouts/home.njk layout: home.njk
eleventyNavigation: eleventyNavigation:
key: i18n.nav.home key: Accueil
order: 1 order: 1
--- ---
{% set maxPosts = collections.posts.length | min(5) %} {% set maxPosts = collections.posts.length | min(5) %}

View File

@ -9,13 +9,6 @@ eleventyExcludeFromCollections: true
<url> <url>
<loc>{{ absoluteUrl }}</loc> <loc>{{ absoluteUrl }}</loc>
<lastmod>{{ page.date | htmlDateString }}</lastmod> <lastmod>{{ page.date | htmlDateString }}</lastmod>
{%- set alternateUrls = page.url | locale_links %}
{%- if alternateUrls.length %}
<xhtml:link rel="alternate" hreflang="{{ page.data.page.lang }}" href="{{ absoluteUrl }}"/>
{%- for link in alternateUrls %}
<xhtml:link rel="alternate" hreflang="{{ link.lang }}" href="{{ link.url | htmlBaseUrl(metadata.url) }}"/>
{%- endfor %}
{%- endif %}
</url> </url>
{%- endfor %} {%- endfor %}
</urlset> </urlset>

View File

@ -9,7 +9,7 @@ pagination:
- posts - posts
- tagList - tagList
addAllPagesToCollections: true addAllPagesToCollections: true
layout: layouts/home.njk layout: home.njk
eleventyComputed: eleventyComputed:
title: Tags “{{ tag }}” title: Tags “{{ tag }}”
permalink: /tags/{{ tag | slugify }}/ permalink: /tags/{{ tag | slugify }}/

View File

@ -1,4 +1,5 @@
@import "prismjs/themes/prism-okaidia.min.css"; @import "prismjs/themes/prism-okaidia.min.css";
/* Defaults */ /* Defaults */
:root { :root {
--font-family: Century Gothic,Avant Garde,Avenir,TeXGyreAdventorRegular,Verdana,sans-serif; --font-family: Century Gothic,Avant Garde,Avenir,TeXGyreAdventorRegular,Verdana,sans-serif;
@ -157,6 +158,10 @@ pre + h2 {
margin-top: 2rem; margin-top: 2rem;
} }
img {
max-width: 100%;
}
figure { figure {
text-align: center; text-align: center;
margin: 0; margin: 0;

1
src/assets/js/index.js Normal file
View File

@ -0,0 +1 @@
import '../css/index.scss';

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

69
webpack.config.common.js Normal file
View File

@ -0,0 +1,69 @@
// Makes Sass faster!
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');
module.exports = {
// Our "entry" point
entry: './src/assets/js/index.js',
output: {
// The global variable name any `exports` from `index.js` will be available at
library: 'SITE',
// Where webpack will compile the assets
path: path.resolve(__dirname, 'src/compiled-assets'),
},
module: {
rules: [
// Transpile and polyfill our JavaScript
{
test: /\.js$/,
use: 'babel-loader',
exclude: /node_modules/,
},
{
// Setting up compiling our Sass
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
{
loader: 'css-loader',
options: {
url: false,
},
},
{
loader: 'postcss-loader',
},
{
loader: 'sass-loader',
options: {
// eslint-disable-next-line global-require
implementation: require('sass'),
sassOptions: {
outputStyle: 'expanded',
},
},
},
],
},
],
},
// Any `import`s from `node_modules` will compiled in to a `vendor.js` file.
optimization: {
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all',
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
}),
],
};

8
webpack.config.dev.js Normal file
View File

@ -0,0 +1,8 @@
const { merge } = require('webpack-merge');
const common = require('./webpack.config.common.js');
module.exports = merge(common, {
mode: 'development',
// Allow watching and live reloading of assets
watch: true,
});

View File

@ -1,42 +0,0 @@
const path = require("path");
const ManifestPlugin = require("webpack-manifest-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const isDev = process.env.NODE_ENV === "development";
const baseFilename = isDev ? "index" : "index.[contenthash]";
module.exports = {
mode: isDev ? "development" : "production",
entry: [
path.resolve(__dirname, "public", "js", "index.js"),
path.resolve(__dirname, "public", "css", "index.css"),
],
output: {
path: path.resolve(__dirname, "_site", "assets"),
filename: `${baseFilename}.js`,
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"],
},
],
},
devtool: isDev ? "eval" : "source-map",
plugins: [
new MiniCssExtractPlugin({ filename: `${baseFilename}.css` }),
new ManifestPlugin({ publicPath: "/assets/" }),
],
};

17
webpack.config.prod.js Normal file
View File

@ -0,0 +1,17 @@
const OptimizeCssAssetsPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const { merge } = require('webpack-merge');
const common = require('./webpack.config.common.js');
module.exports = merge(common, {
// Enable minification and tree-shaking
mode: 'production',
optimization: {
minimizer: [
new OptimizeCssAssetsPlugin({}),
new TerserPlugin({
extractComments: false,
}),
],
},
});