first commit
This commit is contained in:
commit
379b9d1a62
24 files changed
+3828
No files matched your search
+125
@@ -0,0 +1,125 @@
|
|||||||
|
|
||||||
|
# Created by https://www.gitignore.io/api/node,macos
|
||||||
|
# Edit at https://www.gitignore.io/?templates=node,macos
|
||||||
|
|
||||||
|
### macOS ###
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
### Node ###
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
.env.test
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# nuxt.js build output
|
||||||
|
.nuxt
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# End of https://www.gitignore.io/api/node,macos
|
||||||
|
|
||||||
|
/public/
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
title: Blog | Cogear.JS – modern static websites generator
|
||||||
|
description:
|
||||||
|
keywords:
|
||||||
|
theme: blog
|
||||||
|
baseUrl: /zhdiary/
|
||||||
|
blog:
|
||||||
|
index: "" # Provide posts to index page
|
||||||
|
regex: "^p/"
|
||||||
|
tagUri: 'tag'
|
||||||
|
perPage: 5
|
||||||
|
split: ===
|
||||||
|
title: "中文 Diary"
|
||||||
|
pages:
|
||||||
|
^p/:
|
||||||
|
layout: post
|
||||||
|
author:
|
||||||
|
login: polvcode
|
||||||
|
avatar: 'https://en.gravatar.com/userimage/35152960/7140205ee2a71cbe54d3f2ac43c0370d.jpg?size=24'
|
||||||
|
link: https://polvcode.dev
|
||||||
Generated
+3198
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "zhdiary",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "My journey through Chinese language",
|
||||||
|
"main": "index.js",
|
||||||
|
"dependencies": {
|
||||||
|
"jstransformer-markdown-it": "^2.1.0",
|
||||||
|
"p-iteration": "^1.1.8",
|
||||||
|
"webpack": "^4.39.1",
|
||||||
|
"webpack-merge": "^4.2.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {},
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Pacharapol Withayasakpunt",
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/patarapolw/zhdiary"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "cogear-plugin-base-url",
|
||||||
|
"description": "Cogear.JS base URL plugin.",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"author": "Pacharapol Withayasakpunt<patarapolw@gmail.com>",
|
||||||
|
"homepage": "https://github.com/patarapolw/cogear-plugin-base-url",
|
||||||
|
"main": "./plugin.js"
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
const path = require("path");
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
apply() {
|
||||||
|
cogear.on("build.page.writeAfter", ([page, html]) => {
|
||||||
|
let BASE_URL = cogear.config.baseUrl || "/";
|
||||||
|
html = html.replace(/(<link rel="stylesheet" href="|<script src=")\//g, `$1${BASE_URL}`);
|
||||||
|
page.writePath = path.join(cogear.options.output, page.path);
|
||||||
|
fs.writeFileSync(page.writePath, html);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "cogear-plugin-blog",
|
||||||
|
"description": "Cogear.JS blog plugin.",
|
||||||
|
"version": "1.1.0",
|
||||||
|
"author": "Pacharapol Withayasakpunt<patarapolw@gmail.com>",
|
||||||
|
"homepage": "https://github.com/patarapolw/cogear-plugin-blog",
|
||||||
|
"main": "./plugin.js"
|
||||||
|
}
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const {forEach} = require('p-iteration');
|
||||||
|
const merge = require('webpack-merge');
|
||||||
|
module.exports = {
|
||||||
|
// Init method
|
||||||
|
async init(){
|
||||||
|
/**
|
||||||
|
* Blog section in config.yaml must look like this (optional):
|
||||||
|
* blog:
|
||||||
|
* index: "news" # `blog` by default, virtual page. If page exists, data will be proceed to that page
|
||||||
|
*/
|
||||||
|
cogear.blog = this;
|
||||||
|
let defaults = {
|
||||||
|
index: 'blog', // Means `auto`, do it for me
|
||||||
|
regex: null,
|
||||||
|
split: '===',
|
||||||
|
tagUri: 'tag',
|
||||||
|
perPage: 5,
|
||||||
|
};
|
||||||
|
cogear.config.blog = cogear.config.blog ? merge(defaults,cogear.config.blog) : defaults;
|
||||||
|
this.config = cogear.config.blog;
|
||||||
|
// this.perPage = cogear.config.blog.perPage || 3
|
||||||
|
this.regex = new RegExp(cogear.config.blog.regex || '^blog\/(?!tag).+','i');
|
||||||
|
// split: new RegExp(cogear.config.blog.regex.cut || '\<p\>[:=_-]{3,}\<\/p\>','img')
|
||||||
|
this.pages = {};
|
||||||
|
// If no existing index page is configured, create one with 'blog' uri
|
||||||
|
if(Object.keys(cogear.pages).includes(cogear.config.blog.index)){
|
||||||
|
this.pages[''] = cogear.pages[cogear.config.blog.index];
|
||||||
|
} else {
|
||||||
|
await this.setIndexPage();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
apply(){
|
||||||
|
// 1. Init on preload (when config has already been loaded)
|
||||||
|
cogear.on('preload.done',async ()=>{
|
||||||
|
await this.init();
|
||||||
|
await this.build();
|
||||||
|
});
|
||||||
|
// 2. Handle pages preloading
|
||||||
|
// cogear.on('build.page.layout',async ([page])=>{
|
||||||
|
// // If it's a blog page - do not render it # Will cause failure without `posts` variable (will set later)
|
||||||
|
// if(this.regex.test(page.uri)){
|
||||||
|
// page.content = page.content.replace(this.regex.split,this.cut) // Hide splitter ====
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// 3. If page changed - watcher
|
||||||
|
cogear.on('watcher.change.page',async(file)=>{
|
||||||
|
if(this.regex.test(file)){
|
||||||
|
await this.rebuild();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cogear.on('watcher.add.page',async(file)=>{
|
||||||
|
if(this.regex.test(file)){
|
||||||
|
await this.rebuild();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cogear.on('watcher.unlink.page',async([file,page])=>{
|
||||||
|
if(this.regex.test(page.uri)){
|
||||||
|
if(this.pages[page.uri]){
|
||||||
|
delete this.pages[page.uri];
|
||||||
|
}
|
||||||
|
await this.rebuild();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// cogear.on('preload.done',async ()=>{
|
||||||
|
// await this.build()
|
||||||
|
// })
|
||||||
|
},
|
||||||
|
async setIndexPage(){
|
||||||
|
let result = await cogear.emit('preload.page',[null,{
|
||||||
|
// title: 'Blog',
|
||||||
|
content: '',
|
||||||
|
__content: '',
|
||||||
|
file: 'blog.md',
|
||||||
|
uri: 'blog',
|
||||||
|
}]);
|
||||||
|
this.pages[''] = result.shift();
|
||||||
|
},
|
||||||
|
async rebuild(){
|
||||||
|
await this.build();
|
||||||
|
Object.entries(this.pages).forEach(async ([uri,page])=>{
|
||||||
|
await cogear.emit('build.page',page);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// Blog index build
|
||||||
|
async build(){
|
||||||
|
let blog = this.pages[''];
|
||||||
|
// Object.keys(this.pages).forEach(key=>{
|
||||||
|
// if(key != ''){
|
||||||
|
// delete this.pages[key];
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
return new Promise(async(resolve)=>{
|
||||||
|
this.tags = [];
|
||||||
|
// Get posts, map and sort them
|
||||||
|
this.posts = Object.entries(cogear.pages)
|
||||||
|
.filter(([file,p])=>this.regex.test(p.uri))
|
||||||
|
.map(([file,post])=>{
|
||||||
|
if(post.tags){
|
||||||
|
this.tags = this.tags.concat(post.tags).filter((v, i, a) => a.indexOf(v) === i);
|
||||||
|
}
|
||||||
|
return post;
|
||||||
|
})
|
||||||
|
// .filter(post=>{
|
||||||
|
// let isTagPage = false;
|
||||||
|
// this.tags.forEach(tag=>{
|
||||||
|
// isTagPage = post.uri == path.join(blog.uri,tag);
|
||||||
|
// });
|
||||||
|
// return !isTagPage;
|
||||||
|
// })
|
||||||
|
.filter(post => {
|
||||||
|
return !Object.keys(this.pages).includes(post.uri);
|
||||||
|
})
|
||||||
|
.map(post=>{
|
||||||
|
if(typeof post.content == 'string'){
|
||||||
|
const m = new RegExp(`^(.+)${this.config.split}(.*)$`, "s").exec(post.content);
|
||||||
|
if(m){
|
||||||
|
post.teaser = m[1];
|
||||||
|
post.content = m[1] + m[2];
|
||||||
|
} else {
|
||||||
|
post.teaser = post.content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return post;
|
||||||
|
})
|
||||||
|
.sort((a,b)=>{
|
||||||
|
let aDate = new Date(a.date).getTime();
|
||||||
|
let bDate = new Date(b.date).getTime();
|
||||||
|
// Sort in DESC order
|
||||||
|
return aDate > bDate ? -1 : 1;
|
||||||
|
});
|
||||||
|
if(!this.posts.length) resolve();
|
||||||
|
await this.buildPages(blog,this.posts);
|
||||||
|
if(this.tags){
|
||||||
|
await forEach(this.tags,(async(tag)=>{
|
||||||
|
let tagPage = {...blog};
|
||||||
|
tagPage.tag = tag;
|
||||||
|
// tagPage.pagination = null
|
||||||
|
tagPage.uri = path.join(this.config.tagUri,tag);
|
||||||
|
// tagPage.path = path.join('tags',tag,'index.html')
|
||||||
|
await this.buildPages(
|
||||||
|
tagPage,
|
||||||
|
this.posts.filter(post=>Array.isArray(post.tags) && post.tags.includes(tag))
|
||||||
|
);
|
||||||
|
tagPage = (await cogear.emit('preload.page',[null,tagPage])).shift();
|
||||||
|
cogear.pages[tagPage.uri] = tagPage;
|
||||||
|
this.pages[tagPage.uri] = tagPage;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async buildPages(page,posts){
|
||||||
|
let paginator = {
|
||||||
|
count: posts.length,
|
||||||
|
current: 1,
|
||||||
|
perPage: this.config.perPage,
|
||||||
|
total: Math.ceil(posts.length/this.config.perPage),
|
||||||
|
next: null,
|
||||||
|
prev: null,
|
||||||
|
baseUri: page.uri,
|
||||||
|
};
|
||||||
|
|
||||||
|
// If there is more than 1 page
|
||||||
|
if(paginator.total > 1){
|
||||||
|
let pageNum = 2;
|
||||||
|
|
||||||
|
while(pageNum <= paginator.total){
|
||||||
|
let newPage = {...page};
|
||||||
|
let start = this.config.perPage*(pageNum-1);
|
||||||
|
let end = start + this.config.perPage;
|
||||||
|
|
||||||
|
newPage.posts = posts.slice(start,end);
|
||||||
|
newPage.path = path.join(page.uri,pageNum + '','index.html');
|
||||||
|
newPage.uri = path.join(page.uri,pageNum + '/');
|
||||||
|
newPage.paginator = {...paginator};
|
||||||
|
newPage.paginator.current = pageNum;
|
||||||
|
if(pageNum < paginator.total){
|
||||||
|
newPage.paginator.next = path.join(page.uri,String(pageNum+1));
|
||||||
|
}
|
||||||
|
if(pageNum > 2){
|
||||||
|
newPage.paginator.prev = path.join(page.uri,String(pageNum-1));
|
||||||
|
} else {
|
||||||
|
newPage.paginator.prev = page.uri;
|
||||||
|
}
|
||||||
|
newPage.content = await cogear.parser.render(newPage.__content, newPage);
|
||||||
|
|
||||||
|
cogear.pages[newPage.uri] = newPage;
|
||||||
|
this.pages[newPage.uri] = newPage;
|
||||||
|
pageNum = pageNum+1;
|
||||||
|
}
|
||||||
|
paginator.next = path.join(page.uri,'2/');
|
||||||
|
page.posts = posts.slice(0,this.config.perPage);
|
||||||
|
page.paginator = paginator;
|
||||||
|
} else {
|
||||||
|
page.posts = posts;
|
||||||
|
page.paginator = {...paginator};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* RECOMMENDED CONFIGURATION VARIABLES: EDIT AND UNCOMMENT THE SECTION BELOW TO INSERT DYNAMIC VALUES FROM YOUR PLATFORM OR CMS.
|
||||||
|
* LEARN WHY DEFINING THESE VARIABLES IS IMPORTANT: https://disqus.com/admin/universalcode/#configuration-variables*/
|
||||||
|
/*
|
||||||
|
var disqus_config = function () {
|
||||||
|
this.page.url = PAGE_URL; // Replace PAGE_URL with your page's canonical URL variable
|
||||||
|
this.page.identifier = PAGE_IDENTIFIER; // Replace PAGE_IDENTIFIER with your page's unique identifier variable
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
(function() { // DON'T EDIT BELOW THIS LINE
|
||||||
|
var d = document, s = d.createElement('script');
|
||||||
|
s.src = 'https://zhdiary.disqus.com/embed.js';
|
||||||
|
s.setAttribute('data-timestamp', +new Date());
|
||||||
|
(d.head || d.body).appendChild(s);
|
||||||
|
})();
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
title: 'Cogear.JS – modern st'
|
||||||
|
---
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
title: Welcome to Cogear.JS blog!
|
||||||
|
date: "2019-08-08"
|
||||||
|
tags:
|
||||||
|
- news
|
||||||
|
---
|
||||||
|
|
||||||
|
We are happy to introduce **Cogear.JS** – modern static websites generator.
|
||||||
|
It's written in [Node.JS](https://nodejs.org) and powered by the latest [Webpack](https://wepback.js.org).
|
||||||
|
|
||||||
|
Read [the docs](/docs) to understand how the system works.
|
||||||
|
|
||||||
|
[Cogear.JS](https://cogearjs.org/images/cogearjs.jpg)]
|
||||||
|
|
||||||
|
As you can see it's even suitable for blogging! Every blog post can have comments via modern services like [Disqus](https://disqus.com). Posts can also be tagged.
|
||||||
|
|
||||||
|
All blog pages are built automatically and rebuilt when proper content pages are changed, added or deleted.
|
||||||
|
|
||||||
|
===
|
||||||
|
|
||||||
|
> Posts can even have teaser which is splitted from main content by 3 and more `=`,`:`,`_`,`--` symbol (new line only).
|
||||||
|
|
||||||
|
To create a blog on your site, please install [`cogear-plugin-blog`](https://github.com/codemotion/cogear-plugin-blog) npm package and follow the instructions in `README.md` file.
|
||||||
|
|
||||||
|
We really appreciate your attention, so it will be great if you write a comment.
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# Cogear.JS theme **blog**
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Theme with blog posts on the home page.
|
||||||
|
|
||||||
|
Simple responsive design. Posts tags support with navigation and pagination.
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
You need to install [`cogear-plugin-blog`](https://github.com/codemotion/cogear-plugin-blog) to use this theme.
|
||||||
|
|
||||||
|
Go to the site folder and install theme with command:
|
||||||
|
```bash
|
||||||
|
yarn add cogear-theme-blog
|
||||||
|
# or
|
||||||
|
npm install cogear-theme-blog
|
||||||
|
```
|
||||||
|
|
||||||
|
After that you need to edit your site `config.yaml` to set up installed theme.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
theme: blog
|
||||||
|
```
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
|
||||||
|
Use `cogear-plugin-blog` options in `./config.yaml`:
|
||||||
|
``` yaml
|
||||||
|
title: Blog | Cogear.JS – modern static websites generator
|
||||||
|
description:
|
||||||
|
keywords:
|
||||||
|
theme: blog
|
||||||
|
blog:
|
||||||
|
index: "" # Provide posts to index page
|
||||||
|
regex: "^p/"
|
||||||
|
tagUri: 'tag'
|
||||||
|
perPage: 5
|
||||||
|
pages:
|
||||||
|
^p/:
|
||||||
|
layout: post
|
||||||
|
author:
|
||||||
|
login: User
|
||||||
|
avatar: 'https://www.gravatar.com/avatar/400caf343d3bab57ab93f63e21a12be7?s=24'
|
||||||
|
link: https://cogearjs.org
|
||||||
|
```
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
You may also want to install in with [`cogear-preset-blog`](https://github.com/codemotion/cogear-preset-blog).
|
||||||
|
|
||||||
|
# Docs
|
||||||
|
|
||||||
|
More info: [https://cogearjs.org/docs/themes](https://cogearjs.org/docs/themes).
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
article.post
|
||||||
|
header: h1 Write a post!
|
||||||
|
.post-content
|
||||||
|
p Go to <code>./src/pages/p</code> folder and create your first post, creating <code>first-post.md</code> file filled with the following content:
|
||||||
|
pre.
|
||||||
|
---
|
||||||
|
title: First post
|
||||||
|
tags:
|
||||||
|
- news
|
||||||
|
---
|
||||||
|
# This is my first post!
|
||||||
|
p Any questions? More info: <a href="https://github.com/codemotion/cogear-template-blog">https://github.com/codemotion/cogear-template-blog</a>
|
||||||
|
a(href="https://cogearjs.org"): img(src="https://cogearjs.org/images/cogearjs.jpg")
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
head
|
||||||
|
title=title
|
||||||
|
link(rel="shortcut icon" href=`${cogear.config.baseUrl || "/"}favicon.ico` type="image/png")
|
||||||
|
body
|
||||||
|
.navbar
|
||||||
|
.container
|
||||||
|
.brand
|
||||||
|
a(href="/") Blog
|
||||||
|
if cogear.blog.tags
|
||||||
|
ul
|
||||||
|
each t in cogear.blog.tags
|
||||||
|
- tName = t[0].toUpperCase() + t.slice(1)
|
||||||
|
li: a(href=`/tags/${t}`)= tName
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
mixin post(post)
|
||||||
|
.card.p-2.post(class=`${post.teaser ? 'teaser' : 'full'}`)
|
||||||
|
.post-meta.mb-3
|
||||||
|
.float-right
|
||||||
|
+date(post.date)
|
||||||
|
.post-meta--author
|
||||||
|
a(href=`${post.author.link}`): img.mr-3(src=`${post.author.avatar}`)
|
||||||
|
a(href=`${post.author.link}`)= post.author.login
|
||||||
|
header
|
||||||
|
if post.teaser
|
||||||
|
h2: a(href=`/${post.uri}`)= post.title
|
||||||
|
else
|
||||||
|
h1= post.title
|
||||||
|
.post-content!= post.teaser ? post.teaser : post.content
|
||||||
|
if !post.teaser
|
||||||
|
a(href="javascript: history.back()") ← Back
|
||||||
|
mixin date(date)
|
||||||
|
- let months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
|
||||||
|
- let d = new Date(date)
|
||||||
|
- month = months[d.getMonth()]
|
||||||
|
time= `${month} ${d.getDate()}`
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
extends layout.pug
|
||||||
|
block head
|
||||||
|
if tag
|
||||||
|
- tagName = tag[0].toUpperCase() + tag.slice(1)
|
||||||
|
- title= `${tagName} | ${title}`
|
||||||
|
if paginator && paginator.current > 1
|
||||||
|
- title = `Page ${paginator.current} | ${title}`
|
||||||
|
title= title
|
||||||
|
block content
|
||||||
|
if tag
|
||||||
|
h1.tag= tagName
|
||||||
|
if content
|
||||||
|
article.page!= content
|
||||||
|
else if posts
|
||||||
|
- let now = new Date()
|
||||||
|
each post in posts
|
||||||
|
if new Date(post.date) < now
|
||||||
|
+post(post)
|
||||||
|
include paginator
|
||||||
|
else
|
||||||
|
include includes/empty
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
include includes/mixins
|
||||||
|
head
|
||||||
|
block head
|
||||||
|
title= title
|
||||||
|
meta(content="width=device-width, height=device-height, initial-scale=1, minimum-scale=1.0, maximum-scale=1" name="viewport")
|
||||||
|
link(rel="shortcut icon" href=`${cogear.config.baseUrl || "/"}favicon.png` type="image/png")
|
||||||
|
link(rel='stylesheet' href='https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css' integrity='sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T' crossorigin='anonymous')
|
||||||
|
body
|
||||||
|
nav.navbar.navbar-dark.bg-success
|
||||||
|
a.ml-3.navbar-brand(href=cogear.config.baseUrl || "/")= cogear.config.blog.title || "BLOG"
|
||||||
|
.container.mt-3
|
||||||
|
.row
|
||||||
|
.col-lg-8.col-md-12
|
||||||
|
block content
|
||||||
|
.col-lg-4.col-md-12
|
||||||
|
include sidebar
|
||||||
|
|
||||||
|
script(src='https://code.jquery.com/jquery-3.3.1.slim.min.js' integrity='sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo' crossorigin='anonymous')
|
||||||
|
script(src='https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js' integrity='sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1' crossorigin='anonymous')
|
||||||
|
script(src='https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js' integrity='sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM' crossorigin='anonymous')
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
if paginator
|
||||||
|
nav.mt-3
|
||||||
|
ul.pagination
|
||||||
|
if paginator.prev !== null
|
||||||
|
li.page-item
|
||||||
|
a.page-link(href=`${cogear.config.baseUrl || "/"}${paginator.prev}`) ← Prev
|
||||||
|
- let page = 1
|
||||||
|
while page <= paginator.total
|
||||||
|
- let range = 2
|
||||||
|
if page == 1 || page == paginator.total || (page >= paginator.current - range && page <= paginator.current + range)
|
||||||
|
if page == paginator.current
|
||||||
|
li.page-item.active
|
||||||
|
a.page-link(href=`${paginator.baseUri}/${page}`)= page
|
||||||
|
else
|
||||||
|
li.page-item
|
||||||
|
a.page-link(href=`${paginator.baseUri}/${page}`)= page
|
||||||
|
else if paginator.current < paginator.total - range && page == paginator.total - 1 || paginator.current > 1+range && page == range
|
||||||
|
li.page-item
|
||||||
|
a.page-link.ellipsis …
|
||||||
|
- page=page+1
|
||||||
|
if paginator.next !== null
|
||||||
|
li.page-item
|
||||||
|
a.page-link(href=`/${paginator.next}`) Next →
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
extends layout.pug
|
||||||
|
block content
|
||||||
|
+post({
|
||||||
|
title:title,
|
||||||
|
teaser: false,
|
||||||
|
tags:tags,
|
||||||
|
content:content,
|
||||||
|
date:date,
|
||||||
|
author: author
|
||||||
|
})
|
||||||
|
|
||||||
|
#disqus_thread
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
aside.card.p-3
|
||||||
|
block sidebar
|
||||||
|
:markdown-it
|
||||||
|
#### Record my journey to Chinese by [@polvcode](https://polvcode.dev)
|
||||||
|
|
||||||
|
a.twitter-timeline(href="https://twitter.com/ChinesePol" data-height="600") Tweets by ChinesePol
|
||||||
|
script(async src="https://platform.twitter.com/widgets.js" charset="utf-8")
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
@@ -0,0 +1 @@
|
|||||||
|
import "./theme.scss";
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
.post {
|
||||||
|
.post-meta {
|
||||||
|
img {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user