From 327e65f3369605363ccfc277f51f722ca5dd0e72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Boe=CC=88s?= Date: Mon, 8 Aug 2016 23:33:42 +0200 Subject: [PATCH] v0.0.4 * Removed legacy converter * Updated security issue in NPM package * Improved documentation * Added .htaccess * More Promises in Generator * Fixed escaping in HTML * Posts without links added * Twitter card added * OG:Image * Fixed broken sitemap --- .gitignore | 1 + LICENSE => LICENSE.txt | 0 README.md | 48 +++++-- converter.js | 117 --------------- htdocs/.htaccess | 5 + htdocs/robots.txt | 2 +- index.js | 4 + lib/generator.js | 221 ++++++++++++++++++----------- lib/js-toolshed/src/js-toolshed.js | 28 +++- lib/post.js | 63 +++++--- lib/post_reader.js | 2 + package.json | 15 +- theme/atom.xml | 12 +- theme/index.html | 34 ++++- theme/post.html | 30 +++- theme/rss.xml | 12 +- theme/sitemap.xml | 2 +- user/_config.json | 1 + 18 files changed, 336 insertions(+), 261 deletions(-) rename LICENSE => LICENSE.txt (100%) delete mode 100755 converter.js create mode 100644 htdocs/.htaccess diff --git a/.gitignore b/.gitignore index 28b174db..e525292d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ user/posts/* !user/posts/.gitkeep htdocs/* !htdocs/robots.txt +!htdocs/.htaccess diff --git a/LICENSE b/LICENSE.txt similarity index 100% rename from LICENSE rename to LICENSE.txt diff --git a/README.md b/README.md index e87667b0..8271ad70 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,45 @@ Blogophon ========= -* Generate HTML-Files from Markdown -* Templating via Mustache -* Generate teaser page(s) -* Generate tag page(s) -* How to include meta stuff in head +[![Dependency Status](https://david-dm.org/fboes/blogophon/status.svg)](https://david-dm.org/fboes/blogophon) +[![devDependency Status](https://david-dm.org/fboes/blogophon/status.svg)](https://david-dm.org/fboes/blogophon#info=devDependencies) +A small and simple Static Site Generator for blogs. -To-do ------ +Features +-------- -* Single file add -* Dropbox ;) +* Generate HTML-Files from Markdown. +* Templating via Mustache. +* Generate teaser page(s). +* Generate tag page(s). +* Will scale images. +* Puts all relevant meta stuff into ``. + +Installation +------------ + +1. Run `npm install` to install all dependencies. +1. Create the `user/config.json` from `user/_config.json` and fill out the necessary variables. +1. Optional: Change the template files in `theme`. + +How it works +------------ + +1. Start Gulp watcher via `gulp watch`. +1. Create new Markdown file in `user/posts`. Do not use any other characters for the filename but letters, numbers, dashes and dots. +1. Optional: Create images in a folder having the same name as the Markdow file you just created. +1. Gulp will automatically create all HTML files. +1. Optional: Use `rsync` to move your HTML files to any remote server you like. + +Version +------- + +Version: 0.0.4 (2016-08-08) + +Legal stuff +----------- + +Author: [Frank Boës](http://3960.org) + +Copyright & license: See [LICENSE.txt](LICENSE.txt) diff --git a/converter.js b/converter.js deleted file mode 100755 index fb8c643d..00000000 --- a/converter.js +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -var fs = require('fs-extra'); -var pkg = JSON.parse(fs.readFileSync('./package.json')); - -var glob = require("glob"); -var readline = require("readline"); -var yamljs = require('yamljs'); - -/** - * Convert given UTC string into Date object - * @param {String} dateString like '2015-11-06 13:21:00+02:00' - * @return {Date} [description] - */ -var DateSetFromIsoString = function (dateString) { - var dateValues = dateString.match(/^(\d+)\-(\d+)\-(\d+)(?:.(\d+):(\d+):(\d+)(?:(\+|\-)(\d+)\:(\d+))?)?/), i, that = new Date(); - if (dateValues) { - for (i = 0; i <= 9; i++) { - if (!dateValues[i]) { - switch (i) { - case 7: - dateValues[i] = (that.getTimezoneOffset() >= 0) ? '+' : '-'; - break; - case 8: - dateValues[i] = Math.abs(that.getTimezoneOffset()/60); - break; - default: - dateValues[i] = 0; - break; - } - } else if (i !== 7) { - dateValues[i] = parseInt(dateValues[i]); - } - } - that = new Date(Date.UTC( - (dateValues[3]), - (dateValues[2] - 1), - (dateValues[1]), - ((dateValues[7] === '+') ? dateValues[4] - dateValues[8] : dateValues[4] + dateValues[8]), - ((dateValues[7] === '+') ? dateValues[5] - dateValues[9] : dateValues[5] + dateValues[9]), - (dateValues[6]) - )); - return that; - } - throw "No valid ISO time string"; -}; - -var fileConvert = function(file, newFile) { - var yaml = '', - markdown = '', - readYaml = false, - fileStat - ; - - fs.stat(file, function(err, stats) { - fileStat = stats; - }); - - var lineReader = readline.createInterface({ - input: require('fs').createReadStream( file ) - }).on('line', function (line) { - if (line === '---' && yaml === '') { - yaml += "# YML start\n"; - readYaml = true; - } else if (line === '---' && readYaml) { - yaml = yamljs.parse(yaml); - readYaml = false; - } else if (readYaml) { - yaml += line + "\n"; - } else if (!readYaml) { - markdown += line.replace(/\[plugin:embed\]\((.+?)\)/,'$1') + "\n"; - } - }) - .once('close',function () { - var date; - - if (yaml.title !== undefined) { - markdown = 'Title: '+yaml.title+" \n\n"+yaml.title + "\n===============\n"+markdown; - } - if (yaml.publish_date !== undefined) { - date = new DateSetFromIsoString(yaml.publish_date); - } else if (yaml.date !== undefined) { - date = new DateSetFromIsoString(yaml.date); - } else if (fileStat.mtime !== undefined) { - date = fileStat.mtime; - } - if (date) { - markdown = 'Date: '+ date + " \n"+markdown; - } - - if (yaml.taxonomy.tag !== undefined) { - markdown = 'Keywords: '+yaml.taxonomy.tag.join(', ')+" \n"+markdown; - } - fs.writeFile(newFile, markdown); - console.log("Wrote "+newFile); - }); -}; - -var reg = new RegExp(pkg.directories.import); -glob(pkg.directories.import + "/**/*.md", function (er, files) { - var i; - for (i = 0; i < files.length; i++) { - var target = files[i] - .replace(reg, pkg.directories.data) - .replace(/\/item.[a-z]+(.md)$/,'$1') - ; - fileConvert(files[i], target); - } -}); - -glob(pkg.directories.import + "/**/*.{png,jpg,gif}", function (er, files) { - var i; - for (i = 0; i < files.length; i++) { - fs.copySync(files[i], files[i].replace(reg, pkg.directories.data)); - } -}); diff --git a/htdocs/.htaccess b/htdocs/.htaccess new file mode 100644 index 00000000..f3e258ae --- /dev/null +++ b/htdocs/.htaccess @@ -0,0 +1,5 @@ +AddType text/xml rss +AddType text/xml xml +AddType text/plain md +AddType application/json .json +AddCharset utf-8 .html .css .js .rss .xml .md .json diff --git a/htdocs/robots.txt b/htdocs/robots.txt index ff8853f8..70e30e3c 100644 --- a/htdocs/robots.txt +++ b/htdocs/robots.txt @@ -1,4 +1,4 @@ -# robots.txt zu http://www.example.org/ +# http://www.robotstxt.org/ User-agent: * Sitemap: http://journal.3960.org/sitemap.xml diff --git a/index.js b/index.js index ac4b3c4d..b53ba24e 100755 --- a/index.js +++ b/index.js @@ -9,6 +9,10 @@ Generator function (post) { Generator.buildAllPages(); Generator.copyImages(); + if(process.argv[2] !== undefined && process.argv[2] === '--deploy') { + Generator.deploy(); + } } ) ; + diff --git a/lib/generator.js b/lib/generator.js index f9cda876..8b321bd9 100644 --- a/lib/generator.js +++ b/lib/generator.js @@ -24,6 +24,19 @@ var templates = { atom: fs.readFileSync(config.directories.theme+'/atom.xml', 'utf8'), sitemap: fs.readFileSync(config.directories.theme+'/sitemap.xml', 'utf8') }; + +Mustache.escape = function (string) { + var entityMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"' + }; + return String(string).replace(/[&<>"]/g, function (s) { + return entityMap[s]; + }); +} + Object.keys(templates).map(function (template) { Mustache.parse(template); }); @@ -37,13 +50,13 @@ Generator.getArticles = function() { return new Promise ( function(resolve, reject) { glob(config.directories.data + "/**/*.md", function (er, files) { - var i, finished = 0; + var i, finishedFiles = 0; PostReader.on('parsed', function (post) { index.push(post); - finished ++; - if (finished === files.length) { + finishedFiles ++; + if (finishedFiles === files.length) { index.makeNextPrev(); - resolve( finished ); + resolve( finishedFiles ); } }); for (i = 0; i < files.length; i++) { @@ -54,90 +67,136 @@ Generator.getArticles = function() { ); }; +Generator.buildAllArticles = function () { + var i, allPosts = index.getPosts(), processed = 0, maxProcessed = allPosts.length; + + return new Promise ( + function(resolve, reject) { + var checkProcessed = function(filename) { + processed ++; + if (processed === maxProcessed) { + console.log("Created "+processed+" articles"); + resolve( processed ); + } + }; + + for (i = 0; i < allPosts.length; i++) { + var post = allPosts[i]; + shell.mkdir('-p', config.directories.htdocs + '/' + post.meta.Url); + fs.writeFile(config.directories.htdocs + post.meta.Url + 'index.html', Mustache.render(templates.post, { + post: post, + config: config + }),checkProcessed( post.meta.Url + 'index.html')); + } + } + ); +}; + +Generator.buildSpecialPages = function () { + var pagedPosts = index.getPagedPosts(5), + page, + indexFilename, + i, + allPosts = index.getPosts(), + tags = index.getTags(), + processed = 0, + maxProcessed = 4 + pagedPosts.length + Object.keys(tags).length + ; + + return new Promise ( + function(resolve, reject) { + var checkProcessed = function(filename) { + // console.log("Wrote " + filename); + processed ++; + if (processed === maxProcessed) { + console.log("Created "+processed+" special pages"); + resolve( processed ); + } + }; + + fs.remove(config.directories.htdocs + '/index*', function (err) { + for (page = 0; page < pagedPosts.length; page ++) { + var curPageObj = index.getPageData(page, pagedPosts.length); + curPageObj.index = pagedPosts[page]; + curPageObj.config = config; + fs.writeFile(config.directories.htdocs + '/' + curPageObj.currentUrl, Mustache.render(templates.index, curPageObj), checkProcessed('index file')); + } + }); + + fs.remove(config.directories.htdocs + '/tagged', function (err) { + Object.keys(tags).map(function (key) { + shell.mkdir('-p', config.directories.htdocs + '/tagged/' + tags[key].id); + tags[key].config = config; + fs.writeFile(config.directories.htdocs + '/tagged/' + tags[key].id + '/index.html', Mustache.render(templates.index, tags[key]), checkProcessed("/tagged/" + tags[key].id + '/index.html')); + }); + }); + + fs.writeFile(config.directories.htdocs + '/posts.rss', Mustache.render(templates.rss, { + index: index.getPosts(10), + pubDate: dateFormat(index.pubDate, 'ddd, dd mmm yyyy hh:MM:ss o'), + config: config + }), checkProcessed('/posts.rss')); + + fs.writeFile(config.directories.htdocs + '/rss.json', JSON.stringify(RssJs(index.getPosts(20), dateFormat(index.pubDate, 'ddd, dd mmm yyyy hh:MM:ss o'))), checkProcessed('/rss.json')); + + fs.writeFile(config.directories.htdocs + '/posts.atom', Mustache.render(templates.atom, { + index: index.getPosts(10), + pubDate: dateFormat(index.pubDate, 'isoDateTime'), + config: config + }), checkProcessed('/posts.atom')); + + fs.writeFile(config.directories.htdocs + '/sitemap.xml', Mustache.render(templates.sitemap, { + index: index.getPosts(10), + config: config + }), checkProcessed('/sitemap.xml')); + } + ); +}; + +Generator.copyImages = function () { + var i, j, processed = 0, maxProcessed = -1; + return new Promise ( + function(resolve, reject) { + glob(config.directories.data + "/**/*.{png,jpg,gif}", function (er, files) { + maxProcessed = files.length * (config.imageSizes.length + 1); + var checkProcessed = function () { + processed ++; + if (processed === maxProcessed) { + console.log("Created "+processed+" images"); + resolve( processed ); + } + }; + for (i = 0; i < files.length; i++) { + var targetFile = files[i].replace(/^user\//, config.directories.htdocs + '/'); + gm(files[i]) + .noProfile() + .write(targetFile,checkProcessed) + ; + for (j = 0; j < config.imageSizes.length; j++) { + var imageSize = config.imageSizes[j]; + gm(files[i]) + .resize(imageSize[0], imageSize[1]) + .noProfile() + .write(targetFile.replace(/(\.[a-z]+$)/,'-'+imageSize[0]+'x'+imageSize[1]+'$1'),checkProcessed) + ; + } + } + }); + } + ); +}; + /** * [buildOtherPages description] * @return {[type]} [description] */ Generator.buildAllPages = function ( ) { - var pagedPosts = index.getPagedPosts(5), page, indexFilename, i, allPosts = index.getPosts(); - var fileReady = function(filename) { - console.log("Wrote " + filename); - }; - console.log(allPosts); - - for (i = 0; i < allPosts.length; i++) { - var post = allPosts[i]; - shell.mkdir('-p', config.directories.htdocs + '/' + post.meta.Url); - fs.writeFile(config.directories.htdocs + post.meta.Url + 'index.html', Mustache.render(templates.post, { - post: post, - config: config - }),fileReady( post.meta.Url + 'index.html')); - } - - fs.remove(config.directories.htdocs + '/index*', function (err) { - for (page = 0; page < pagedPosts.length; page ++) { - var curPageObj = index.getPageData(page, pagedPosts.length); - curPageObj.index = pagedPosts[page]; - curPageObj.config = config; - fs.writeFile(config.directories.htdocs + '/' + curPageObj.currentUrl, Mustache.render(templates.index, curPageObj), fileReady('index file')); - } - }); - - fs.writeFile(config.directories.htdocs + '/sitemap.json', JSON.stringify(allPosts), fileReady("/sitemap.json")); - - fs.writeFile(config.directories.htdocs + '/posts.rss', Mustache.render(templates.rss, { - index: index.getPosts(10), - pubDate: dateFormat(index.pubDate, 'ddd, dd mmm yyyy hh:MM:ss o'), - config: config - }), fileReady('/posts.rss')); - - fs.writeFile(config.directories.htdocs + '/rss.json', JSON.stringify(RssJs(allPosts, dateFormat(index.pubDate, 'ddd, dd mmm yyyy hh:MM:ss o'))), fileReady('/rss.json')); - - fs.writeFile(config.directories.htdocs + '/posts.atom', Mustache.render(templates.atom, { - index: index.getPosts(10), - pubDate: dateFormat(index.pubDate, 'isoDateTime'), - config: config - }), fileReady('/posts.atom')); - - fs.writeFile(config.directories.htdocs + '/sitemap.xml', Mustache.render(templates.sitemap, { - index: index.getPosts(10), - config: config - }), fileReady('/sitemap.xml')); - - var tags = index.getTags(); - fs.remove(config.directories.htdocs + '/tagged', function (err) { - Object.keys(tags).map(function (key) { - shell.mkdir('-p', config.directories.htdocs + '/tagged/' + tags[key].id); - tags[key].config = config; - fs.writeFile(config.directories.htdocs + '/tagged/' + tags[key].id + '/index.html', Mustache.render(templates.index, tags[key]), fileReady("/tagged/" + tags[key].id + '/index.html')); - }); - }); + Generator.buildAllArticles(); + Generator.buildSpecialPages(); }; -Generator.copyImages = function () { - glob(config.directories.data + "/**/*.{png,jpg,gif}", function (er, files) { - var i, j, copiedFiles = 0; - var copyEnd = function () { - copiedFiles ++; - if (copiedFiles === files.length) { - console.log("Copied "+copiedFiles+" images"); - } - }; - for (i = 0; i < files.length; i++) { - var targetFile = files[i].replace(/^user\//, config.directories.htdocs + '/'); - fs.copy(files[i], targetFile, copyEnd); - for (j = 0; j < config.imageSizes.length; j++) { - var imageSize = config.imageSizes[j]; - gm(files[i]) - .resize(imageSize[0], imageSize[1]) - .noProfile() - .write(targetFile.replace(/(\.[a-z]+$)/,'-'+imageSize[0]+'x'+imageSize[1]+'$1'),function() { - - }) - ; - } - } - }); +Generator.deploy = function () { + console.log('# ' + config.deploy); }; module.exports = Generator; diff --git a/lib/js-toolshed/src/js-toolshed.js b/lib/js-toolshed/src/js-toolshed.js index f0f388d0..11ce5544 100644 --- a/lib/js-toolshed/src/js-toolshed.js +++ b/lib/js-toolshed/src/js-toolshed.js @@ -29,13 +29,27 @@ return that; }; - /** - * Convert `#string` into `string`. - * @return {String} [description] - */ - String.prototype.fromId = function () { - return this.replace(/^#/,''); - }; + /** + * Convert `#string` into `string`. + * @return {String} [description] + */ + String.prototype.fromId = function () { + return this.replace(/^#/,''); + }; + + /** + * Remove any special characters from string and convert into lowercase. + * @return {String} [description] + */ + String.prototype.asciify = function () { + return this.toLowerCase() + .replace(/[äáàâ]/g,'a') + .replace(/[üúùû]/g,'u') + .replace(/[öóòô]/g,'o') + .replace(/[ëéèê]/g,'o') + .replace(/[^a-z0-9]/g,'-') + ; + }; /** * Convert `#string` into `string`. diff --git a/lib/post.js b/lib/post.js index a3175be8..4ab45596 100644 --- a/lib/post.js +++ b/lib/post.js @@ -10,32 +10,54 @@ var markyMark = function (html, relUrl) { if (relUrl) { html = html.replace(/(!\[.+?\]\()/g, '$1'+relUrl); } + + var entityMap = { + '...': '…', + '… …': '…', + '(C)': '©', + '(R)': '®', + '(TM)': '™', + '(+-)': '±', + '(1/4)': '¼', + '(1/2)': '½', + '(3/4)': '¾', + '->': '→', + '=>': '⇒', + '<-': '←', + '<=': '⇐' + }; + + html = html.replace(/(\.\.\.|… …|\(C\)|\(R\)|\(TM\)|\(+-\)|\(1\/4\)|\(1\/2\)|\(3\/4\)|->|=>|<-|<=)/g, function (s) { + return entityMap[s]; + }); + html = html .replace(/\s--\s/g, ' — ') - .replace(/\.\.\./g, '…') - .replace(/… …/g, '… ') - .replace(/\(C\)/g, '©') - .replace(/\(R\)/g, '®') - .replace(/\(TM\)/g, '™') - .replace(/\(+-\)/g, '±') - .replace(/\(1\/4\)/g, '¼') - .replace(/\(1\/2\)/g, '½') - .replace(/\(3\/4\)/g, '¾') - .replace(/->/g, '→') - .replace(/=>/g, '⇒') - .replace(/<-/g, '←') - .replace(/<=/g, '⇐') + // .replace(/\.\.\./g, '…') + // .replace(/… …/g, '… ') + // .replace(/\(C\)/g, '©') + // .replace(/\(R\)/g, '®') + // .replace(/\(TM\)/g, '™') + // .replace(/\(+-\)/g, '±') + // .replace(/\(1\/4\)/g, '¼') + // .replace(/\(1\/2\)/g, '½') + // .replace(/\(3\/4\)/g, '¾') + // .replace(/->/g, '→') + // .replace(/=>/g, '⇒') + // .replace(/<-/g, '←') + // .replace(/<=/g, '⇐') .replace(/(\d)\s*-\s*(\d)/g,'$1–$2') .replace(/(\s)-(\s)/g,'$1–$2') .replace(/(\d\s*)(x|\*)(\s*\d)/g,'$1×$3') - .replace(/"(\S.*?\S)"/g,'„$1“') - .replace(/'(\S.*?\S)'/g,'‚$1‘') + .replace(/([^\S])"(\S.*?\S)"([^\S])/g,'$1„$2“$3') + .replace(/([^\S])'(\S.*?\S)'([^\S])/g,'$1‚$2‘$3') ; return markdownConvert(html) .replace(/

===<\/p>/g,'') .replace(/(<\/?h)3/g,'$14') .replace(/(<\/?h)2/g,'$13') .replace(/(<\/?h)1/g,'$12') + //.replace(/(

[\s\S]+?[^>])(\n[\s\S]+?<\/blockquote>)/g,'$1
$2') .replace( /(

)\s*(?:)?[^<]*?youtube.+v=([a-zA-Z0-9\-_]+)[^>]*?(?:<\/a>)?\s*(<\/p>)/g, '

' @@ -53,6 +75,7 @@ var markyMark = function (html, relUrl) { */ var Post = function (markdown, meta) { var htmlTeaser = markyMark(meta.Description.trim() || '', meta.Url); + var html = markyMark(markdown, meta.Url); if (meta.Keywords !== undefined) { meta.Tags = []; meta.Keywords.trim().split(/,\s+/).forEach(function(tag){ @@ -65,6 +88,12 @@ var Post = function (markdown, meta) { if (meta.Classes === undefined) { meta.Classes = ''; } + if (meta.Image === undefined) { + var match = htmlTeaser.match(/ {{config.name}} - - {{{config.baseUrl}}}{{{config.basePath}}} + + {{config.baseUrl}}{{config.basePath}} {{pubDate}} - + {{config.name}} {{#index}} {{meta.Title}} - - + + {{meta.isoDate}} - {{{config.baseUrl}}}{{{config.basePath}}}{{{meta.Url}}} + {{config.baseUrl}}{{config.basePath}}{{meta.Url}} {{#meta.Tags}} {{/meta.Tags}} diff --git a/theme/index.html b/theme/index.html index 4bcf882a..e9478d4b 100644 --- a/theme/index.html +++ b/theme/index.html @@ -2,8 +2,8 @@ - {{#title}}{{title}} - {{/title}}{{config.name}} - + {{#title}}{{title}} | {{/title}}{{config.name}} + @@ -17,6 +17,11 @@ + {{#config.twitterAccount}} + + + + {{/config.twitterAccount}} {{#config.themeColor}} {{/config.themeColor}} @@ -39,9 +44,11 @@

{{title}}

-

{{meta.Title}}

+

{{meta.Title}}

{{{htmlTeaser}}} -

Weiter lesen

+ {{^meta.noLinkNeeded}} +

Weiter lesen

+ {{/meta.noLinkNeeded}} {{#meta.Tags.length}}

Andere Artikel zum Thema @@ -83,7 +90,22 @@

Links

Über…

Merkwürdige Erlebnisse, spontane Einfälle, interessante Entdeckungen und ein paar Meinungen aus dem Leben von Frank Boës. Man kann mich auch gerne Frank Boes schreiben, aber die Aussprache bleibt bitte [bo:s].

- + +

Suche

+
+ + +
+ +

Abonnement

+

Neuerungen auf dieser Seite kann man auch mit einem Newsreader abonnieren:

+ + +
@@ -92,6 +114,6 @@

Über…

- + diff --git a/theme/post.html b/theme/post.html index 2d8ded1d..52c36b12 100644 --- a/theme/post.html +++ b/theme/post.html @@ -2,12 +2,15 @@ - {{post.meta.Title}} - {{config.name}} - + {{post.meta.Title}} | {{config.name}} + + {{#post.meta.Image}} + + {{/post.meta.Image}} {{#post.meta.Keywords}} {{/post.meta.Keywords}} @@ -20,6 +23,11 @@ + {{#config.twitterAccount}} + + + + {{/config.twitterAccount}} {{#config.themeColor}} {{/config.themeColor}} @@ -69,6 +77,22 @@

Links

Über…

Merkwürdige Erlebnisse, spontane Einfälle, interessante Entdeckungen und ein paar Meinungen aus dem Leben von Frank Boës. Man kann mich auch gerne Frank Boes schreiben, aber die Aussprache bleibt bitte [bo:s].

+ + +

Suche

+
+ + +
+ +

Abonnement

+

Neuerungen auf dieser Seite kann man auch mit einem Newsreader abonnieren:

+ + @@ -78,6 +102,6 @@

Über…

- + diff --git a/theme/rss.xml b/theme/rss.xml index df87f692..6280424a 100644 --- a/theme/rss.xml +++ b/theme/rss.xml @@ -1,19 +1,19 @@ - + {{config.name}} - {{{config.baseUrl}}}{{{config.basePath}}} + {{config.baseUrl}}{{config.basePath}} {{config.description}} {{config.language}} {{pubDate}} - + {{#index}} {{meta.Title}} - - {{{config.baseUrl}}}{{{config.basePath}}}{{{meta.Url}}} + + {{config.baseUrl}}{{config.basePath}}{{meta.Url}} {{meta.rfcDate}} - {{{config.baseUrl}}}{{{config.basePath}}}{{{meta.Url}}} + {{config.baseUrl}}{{config.basePath}}{{meta.Url}} {{#meta.Tags}} {{title}} {{/meta.Tags}} diff --git a/theme/sitemap.xml b/theme/sitemap.xml index 6e2b281d..fc76a57e 100644 --- a/theme/sitemap.xml +++ b/theme/sitemap.xml @@ -3,6 +3,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"> {{#index}} - {{{config.baseUrl}}{{config.basePath}}}{{{meta.Url}}}{{meta.isoDate}} + {{config.baseUrl}}{{config.basePath}}{{meta.Url}}{{meta.isoDate}} {{/index}} diff --git a/user/_config.json b/user/_config.json index ba5715da..3822e687 100644 --- a/user/_config.json +++ b/user/_config.json @@ -5,6 +5,7 @@ "description": "Most-simple blog", "language": "en", "siteEmail": "", + "twitterAccount": "", "themeColor": "#ffffff", "deploy":"", "imageSizes": [