diff --git a/.eleventy.js b/.eleventy.js index b1241bb9..91a7bf39 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -20,112 +20,116 @@ const javascript = require("./src/config/processors/javascript"); // π οΈ Utilities const filterPostDate = require("./src/config/filters/postDate"); const filterIsoDate = require("./src/config/filters/isoDate"); +const filterTitleCase = require("./src/config/filters/titleCase"); const isProduction = process.env.ELEVENTY_ENV === "PROD"; module.exports = function (eleventyConfig) { - // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ - // LANGUAGES - // Using Eleventy's build events to process non-template languages - // Learn more: https://www.11ty.dev/docs/events/ - // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ - - /* - * JavaScript & CSS Processing - * These processors handle bundling, transpiling, and minification - * - JavaScript: Compiled with esbuild for modern bundling - * - CSS/LESS: Processed and minified for production, including a PostCSS pipeline - */ - eleventyConfig.on("eleventy.after", javascript); - eleventyConfig.on("eleventy.after", less); - - // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ - // PLUGINS - // Extend Eleventy with additional functionality - // Learn more: https://www.11ty.dev/docs/plugins/ - // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ - - /* - * πΌοΈ Image Optimization - * Resize and optimize images for better performance using {% getUrl %} - * Documentation: https://github.com/CodeStitchOfficial/eleventy-plugin-sharp-images - */ - eleventyConfig.addPlugin(pluginImages, configImages); - - /* - * πΊοΈ Sitemap Generation - * Creates sitemap.xml automatically using domain from _data/client.json - * Documentation: https://github.com/quasibit/eleventy-plugin-sitemap - */ - eleventyConfig.addPlugin(pluginSitemap, configSitemap); - - /* - * π¦ Production Minification - * Minifies HTML, CSS, JSON, XML, XSL, and webmanifest files - * Only runs during production builds (npm run build) - * Documentation: https://github.com/CodeStitchOfficial/eleventy-plugin-minify - */ - if (isProduction) { - eleventyConfig.addPlugin(pluginMinifier); - } - - // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ - // PASSTHROUGH COPIES - // Copy files directly to output without processing - // Learn more: https://www.11ty.dev/docs/copy/ - // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ - - eleventyConfig.addPassthroughCopy("./src/assets"); // Static assets - eleventyConfig.addPassthroughCopy("./src/admin"); // CMS admin files - eleventyConfig.addPassthroughCopy("./src/_redirects"); // Redirect rules - - // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ - // FILTERS - // Transform data in templates at build time - // Learn more: https://www.11ty.dev/docs/filters/ - // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ - - /* - * π Human-Readable Date Formatting Filter - * Converts JavaScript dates to human-readable format - * Usage: {{ "2023-12-02" | postDate }} - * Powered by Luxon: https://moment.github.io/luxon/api-docs/ - */ - eleventyConfig.addFilter("postDate", filterPostDate); - - /* - * π ISO Date Formatting Filter - * Converts JavaScript dates to ISO 8601 format - * Usage: {{ "2023-12-02" | isoDate }} - * Powered by Luxon: https://moment.github.io/luxon/api-docs/ - */ - eleventyConfig.addFilter("isoDate", filterIsoDate); - - // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ - // SHORTCODES - // Generate dynamic content with JavaScript - // Learn more: https://www.11ty.dev/docs/shortcodes/ - // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ - - /* - * π Current Year Shortcode - * Outputs the current year (useful for copyright notices) - * Usage: {% year %} - * Updates automatically with each build - */ - eleventyConfig.addShortcode("year", () => `${new Date().getFullYear()}`); - - // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ - // BUILD CONFIGURATION - // Define input/output directories and template engine - // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ - - return { - dir: { - input: "src", // Source files directory - output: "public", // Build output directory - includes: "_includes", // Partial templates directory - data: "_data", // Global data files directory - }, - htmlTemplateEngine: "njk", // Nunjucks for HTML templates - }; + // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ + // LANGUAGES + // Using Eleventy's build events to process non-template languages + // Learn more: https://www.11ty.dev/docs/events/ + // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ + + /* + * JavaScript & CSS Processing + * These processors handle bundling, transpiling, and minification + * - JavaScript: Compiled with esbuild for modern bundling + * - CSS/LESS: Processed and minified for production, including a PostCSS pipeline + */ + eleventyConfig.on("eleventy.after", javascript); + eleventyConfig.on("eleventy.after", less); + + // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ + // PLUGINS + // Extend Eleventy with additional functionality + // Learn more: https://www.11ty.dev/docs/plugins/ + // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ + + /* + * πΌοΈ Image Optimization + * Resize and optimize images for better performance using {% getUrl %} + * Documentation: https://github.com/CodeStitchOfficial/eleventy-plugin-sharp-images + */ + eleventyConfig.addPlugin(pluginImages, configImages); + + /* + * πΊοΈ Sitemap Generation + * Creates sitemap.xml automatically using domain from _data/client.json + * Documentation: https://github.com/quasibit/eleventy-plugin-sitemap + */ + eleventyConfig.addPlugin(pluginSitemap, configSitemap); + + /* + * π¦ Production Minification + * Minifies HTML, CSS, JSON, XML, XSL, and webmanifest files + * Only runs during production builds (npm run build) + * Documentation: https://github.com/CodeStitchOfficial/eleventy-plugin-minify + */ + if (isProduction) { + eleventyConfig.addPlugin(pluginMinifier); + } + + // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ + // PASSTHROUGH COPIES + // Copy files directly to output without processing + // Learn more: https://www.11ty.dev/docs/copy/ + // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ + + eleventyConfig.addPassthroughCopy("./src/assets"); // Static assets + eleventyConfig.addPassthroughCopy("./src/admin"); // CMS admin files + eleventyConfig.addPassthroughCopy("./src/_redirects"); // Redirect rules + + // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ + // FILTERS + // Transform data in templates at build time + // Learn more: https://www.11ty.dev/docs/filters/ + // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ + + // Custom filter to convert file slug to title case (e.g., about-us -> About Us) + eleventyConfig.addFilter("titleCase", filterTitleCase); + + /* + * π Human-Readable Date Formatting Filter + * Converts JavaScript dates to human-readable format + * Usage: {{ "2023-12-02" | postDate }} + * Powered by Luxon: https://moment.github.io/luxon/api-docs/ + */ + eleventyConfig.addFilter("postDate", filterPostDate); + + /* + * π ISO Date Formatting Filter + * Converts JavaScript dates to ISO 8601 format + * Usage: {{ "2023-12-02" | isoDate }} + * Powered by Luxon: https://moment.github.io/luxon/api-docs/ + */ + eleventyConfig.addFilter("isoDate", filterIsoDate); + + // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ + // SHORTCODES + // Generate dynamic content with JavaScript + // Learn more: https://www.11ty.dev/docs/shortcodes/ + // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ + + /* + * π Current Year Shortcode + * Outputs the current year (useful for copyright notices) + * Usage: {% year %} + * Updates automatically with each build + */ + eleventyConfig.addShortcode("year", () => `${new Date().getFullYear()}`); + + // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ + // BUILD CONFIGURATION + // Define input/output directories and template engine + // βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ + + return { + dir: { + input: "src", // Source files directory + output: "public", // Build output directory + includes: "_includes", // Partial templates directory + data: "_data", // Global data files directory + }, + htmlTemplateEngine: "njk", // Nunjucks for HTML templates + }; }; diff --git a/package.json b/package.json index aa214e5b..f7997322 100644 --- a/package.json +++ b/package.json @@ -1,45 +1,46 @@ { - "name": "intermediate-website-kit-less", - "version": "2.0.1", - "description": "The official CodeStitch Intermediate kit, featuring 11ty, Decap CMS and LESS - all set up for you! Perfect for websites of all sizes.", - "main": "index.js", - "scripts": { - "watch:cms": "npx decap-server", - "watch:eleventy": "cross-env ELEVENTY_ENV=DEV eleventy --serve", - "build:eleventy": "cross-env ELEVENTY_ENV=PROD eleventy", - "start": "run-p watch:*", - "build": "run-s build:*", - "preview": "cross-env ELEVENTY_ENV=PROD eleventy --serve", - "remove-dark-mode": "node scripts/remove-dark-mode.js", - "remove-decap": "node scripts/remove-decap.js", - "remove-demo": "node scripts/remove-demo.js" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/CodeStitchOfficial/Intermediate-Website-Kit-LESS.git" - }, - "keywords": [], - "author": "", - "license": "ISC", - "bugs": { - "url": "https://github.com/CodeStitchOfficial/Intermediate-Website-Kit-LESS/issues" - }, - "homepage": "https://github.com/CodeStitchOfficial/Intermediate-Website-Kit-LESS#readme", - "dependencies": { - "@11ty/eleventy": "^3.1.2", - "@codestitchofficial/eleventy-plugin-minify": "^1.1.3", - "@codestitchofficial/eleventy-plugin-sharp-images": "^2.2.0", - "@quasibit/eleventy-plugin-sitemap": "^2.2.0", - "autoprefixer": "^10.4.27", - "codestitch-sharp-image-automation": "^0.4.0", - "cross-env": "^10.1.0", - "cssnano": "^7.1.2", - "decap-server": "^3.5.2", - "esbuild": "^0.27.3", - "glob": "^13.0.6", - "less": "^4.5.1", - "netlify-plugin-cache": "^1.0.3", - "npm-run-all2": "^5.0.2", - "postcss": "^8.5.6" - } + "name": "intermediate-website-kit-less", + "version": "2.0.1", + "description": "The official CodeStitch Intermediate kit, featuring 11ty, Decap CMS and LESS - all set up for you! Perfect for websites of all sizes.", + "main": "index.js", + "scripts": { + "watch:cms": "npx decap-server", + "watch:eleventy": "cross-env ELEVENTY_ENV=DEV eleventy --serve", + "build:eleventy": "cross-env ELEVENTY_ENV=PROD eleventy", + "start": "run-p watch:*", + "build": "run-s build:*", + "preview": "cross-env ELEVENTY_ENV=PROD eleventy --serve", + "remove-dark-mode": "node scripts/remove-dark-mode.js", + "remove-decap": "node scripts/remove-decap.js", + "remove-demo": "node scripts/remove-demo.js", + "create-page": "node scripts/create-page.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/CodeStitchOfficial/Intermediate-Website-Kit-LESS.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/CodeStitchOfficial/Intermediate-Website-Kit-LESS/issues" + }, + "homepage": "https://github.com/CodeStitchOfficial/Intermediate-Website-Kit-LESS#readme", + "dependencies": { + "@11ty/eleventy": "^3.1.2", + "@codestitchofficial/eleventy-plugin-minify": "^1.1.3", + "@codestitchofficial/eleventy-plugin-sharp-images": "^2.2.0", + "@quasibit/eleventy-plugin-sitemap": "^2.2.0", + "autoprefixer": "^10.4.27", + "codestitch-sharp-image-automation": "^0.4.0", + "cross-env": "^10.1.0", + "cssnano": "^7.1.2", + "decap-server": "^3.5.2", + "esbuild": "^0.27.3", + "glob": "^13.0.6", + "less": "^4.5.1", + "netlify-plugin-cache": "^1.0.3", + "npm-run-all2": "^5.0.2", + "postcss": "^8.5.6" + } } diff --git a/scripts/create-page.js b/scripts/create-page.js new file mode 100644 index 00000000..e51c9050 --- /dev/null +++ b/scripts/create-page.js @@ -0,0 +1,35 @@ +const fs = require("fs"); +const path = require("path"); + +const input = process.argv[2]; + +if (!input) { + console.log('Please provide page names. Example: npm run create-page -- "Contact, About, Services"'); + process.exit(1); +} + +const pages = input.split(",").map((p) => p.trim()); + +const templatePath = path.join("src/content/pages", "_template.txt"); +let template = fs.readFileSync(templatePath, "utf8"); + +pages.forEach((page) => { + const slug = page + .toLowerCase() + .replace(/[^a-z0-9\s-]/g, "") + .replace(/\s+/g, "-") + .replace(/-+/g, "-") + .replace(/^-+|-+$/g, ""); + + if (!slug) return; + + const htmlPath = path.join("src/content/pages", `${slug}.html`); + const lessPath = path.join("src/assets/less", `${slug}.less`); + + // const pageTemplate = template.replaceAll("{{PAGE}}", slug); + + fs.writeFileSync(htmlPath, template); + fs.writeFileSync(lessPath, ""); + + console.log(`Created ${htmlPath} and ${lessPath}`); +}); diff --git a/src/config/filters/titleCase.js b/src/config/filters/titleCase.js new file mode 100644 index 00000000..d3bb11ee --- /dev/null +++ b/src/config/filters/titleCase.js @@ -0,0 +1,8 @@ +function filterTitleCase(value) { + return value + .split("-") + .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join(" "); +} + +module.exports = filterTitleCase; diff --git a/src/content/pages/_template.txt b/src/content/pages/_template.txt index eadf15f3..2f41fd4c 100644 --- a/src/content/pages/_template.txt +++ b/src/content/pages/_template.txt @@ -1,16 +1,33 @@ --- -title: "Page title for