15 |
16 |
17 |
18 | {% excerpt post %}
19 |
20 | Read more
21 |
22 |
23 | {% endfor %}
--------------------------------------------------------------------------------
/posts/2019/blog-post-1.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: post-layout.njk
3 | title: This Is My First Ever Post
4 | date: 2019-05-30
5 | tags: ['post']
6 | ---
7 |
8 |
9 | This is the first post on my blog.
10 |
11 |
12 |
13 | Eleventy is super fresh init.
14 |
15 |
16 | ## Want your own blog?
17 | The code for this blog is available on GitHub:
18 | [https://github.com/JonUK/eleventy-blog](https://github.com/JonUK/eleventy-blog)
19 |
20 |
21 |
--------------------------------------------------------------------------------
/About.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: base-layout.njk
3 | ---
4 | # About this blog
5 |
6 | This blog was created using the Static Site Generator [Eleventy](https://www.11ty.io/) (aka 11ty).
7 | New posts can quickly and easily be added to this blog just by adding new Markdown files.
8 |
9 | The following article details how this blog was created.
10 |
11 | ## Creating A Blog With Eleventy
12 | [https://keepinguptodate.com/pages/2019/06/creating-blog-with-eleventy/](https://keepinguptodate.com/pages/2019/06/creating-blog-with-eleventy/)
13 |
14 |
15 |
--------------------------------------------------------------------------------
/_includes/base-layout.njk:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Eleventy Blog
7 |
8 |
9 |
10 |
11 |
12 |
13 | My Blog
14 | About
15 |
16 |
17 | {{ content | safe }}
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # eleventy-blog
2 | An example blog site using Eleventy that covers fundamental functionality.
3 |
4 | The following article accompanies this repo.
5 |
6 | ## Creating A Blog With Eleventy
7 | [https://keepinguptodate.com/pages/2019/06/creating-blog-with-eleventy/](https://keepinguptodate.com/pages/2019/06/creating-blog-with-eleventy/)
8 |
9 | A demo of the blog is hosted on Netlify:
10 | [https://dazzling-almeida-ca0492.netlify.com/](https://dazzling-almeida-ca0492.netlify.com/)
11 |
12 | ## Branches
13 | This repo contains several branches that allow you to checkout the code at various stages of development.
14 |
15 | ## How do I run the site?
16 | ```
17 | npm install
18 | npm run serve
19 | ```
20 |
21 | Then access the site with the URL [http://localhost:8080/](http://localhost:8080/) (your port may vary).
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eleventy-blog",
3 | "version": "1.1.0",
4 | "description": "An example blog site using Eleventy that covers fundamental functionality",
5 | "scripts": {
6 | "build": "npx eleventy",
7 | "serve": "npx eleventy --serve",
8 | "debug": "DEBUG=* npx eleventy",
9 | "test": "jest"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/JonUK/eleventy-blog.git"
14 | },
15 | "author": "Jon Keeping",
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/JonUK/eleventy-blog/issues"
19 | },
20 | "homepage": "https://github.com/JonUK/eleventy-blog#readme",
21 | "devDependencies": {
22 | "@11ty/eleventy": "^0.12.1",
23 | "jest": "^26.6.3",
24 | "moment": "^2.29.1"
25 | },
26 | "dependencies": {
27 | "@jest/globals": "latest"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/.eleventy.test.js:
--------------------------------------------------------------------------------
1 | const eleventyConfig = require('@11ty/eleventy/src/EleventyConfig');
2 | const eleventy = require('../.eleventy.js');
3 |
4 | let dateReadableFunc;
5 |
6 | beforeAll(() => {
7 | // Populate the config object with all the filters & shortcodes
8 | eleventy(eleventyConfig);
9 |
10 | dateReadableFunc = eleventyConfig.nunjucksFilters['dateReadable'];
11 | });
12 |
13 | describe('dateReadable filter', () => {
14 |
15 | it.each([
16 | ['2019-06-01T00:00:00.000Z', 'June 1, 2019'],
17 | ['2019-06-02T00:00:00.000Z', 'June 2, 2019'],
18 | ['2019-07-01T00:00:00.000Z', 'July 1, 2019'],
19 | ['2020-01-01T00:00:00.000Z', 'January 1, 2020'],
20 | ['2020-01-01T01:00:00.000Z', 'January 1, 2020'],
21 | ['2020-01-01T23:59:59.000Z', 'January 1, 2020'],
22 | ['2020-12-31T23:59:59.000Z', 'December 31, 2020']
23 | ])('can parse %s to %s', (inputString, expected) => {
24 | const outputDateString = dateReadableFunc(inputString);
25 | expect(outputDateString).toEqual(expected);
26 | });
27 |
28 | });
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Jon Keeping
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.eleventy.js:
--------------------------------------------------------------------------------
1 | const moment = require('moment');
2 |
3 | moment.locale('en');
4 |
5 | module.exports = function (eleventyConfig) {
6 |
7 | eleventyConfig.addFilter('dateIso', date => {
8 | return moment(date).toISOString();
9 | });
10 |
11 | eleventyConfig.addFilter('dateReadable', date => {
12 | return moment(date).utc().format('LL'); // E.g. May 31, 2019
13 | });
14 |
15 | eleventyConfig.addShortcode('excerpt', article => extractExcerpt(article));
16 |
17 | // Folders to copy to output folder
18 | eleventyConfig.addPassthroughCopy("css");
19 | };
20 |
21 | function extractExcerpt(article) {
22 | if (!article.hasOwnProperty('templateContent')) {
23 | console.warn('Failed to extract excerpt: Document has no property "templateContent".');
24 | return null;
25 | }
26 |
27 | let excerpt = null;
28 | const content = article.templateContent;
29 |
30 | // The start and end separators to try and match to extract the excerpt
31 | const separatorsList = [
32 | { start: '', end: '' },
33 | { start: '
', end: '
' }
34 | ];
35 |
36 | separatorsList.some(separators => {
37 | const startPosition = content.indexOf(separators.start);
38 |
39 | // This end position could use "lastIndexOf" to return all the paragraphs rather than just the first
40 | // paragraph when matching is on "