first commit

This commit is contained in:
patarapolw committed 2019-08-12 01:13:27 +07:00
commit 379b9d1a62
24 files changed
+3828

No files matched your search

+125
View File
@@ -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
View File
@@ -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
+3198
View File
File diff suppressed because it is too large. Load diff
+22
View File
@@ -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"
}
}
+8
View File
@@ -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"
}
+13
View File
@@ -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);
})
}
}
+8
View File
@@ -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"
}
+200
View File
@@ -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
View File
@@ -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);
})();
+3
View File
@@ -0,0 +1,3 @@
---
title: 'Cogear.JS – modern st'
---
+25
View File
@@ -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.
+54
View File
@@ -0,0 +1,54 @@
# Cogear.JS theme **blog**
![screenshot](https://github.com/codemotion/cogear-theme-blog/raw/master/screenshot.jpg)
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).
+13
View File
@@ -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")
+13
View File
@@ -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
+21
View File
@@ -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()") &larr; 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()}`
+21
View File
@@ -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
+20
View File
@@ -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')
+23
View File
@@ -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}`) &larr; 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 &rarr;
+12
View File
@@ -0,0 +1,12 @@
extends layout.pug
block content
+post({
title:title,
teaser: false,
tags:tags,
content:content,
date:date,
author: author
})
#disqus_thread
+7
View File
@@ -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

+1
View File
@@ -0,0 +1 @@
import "./theme.scss";
+7
View File
@@ -0,0 +1,7 @@
.post {
.post-meta {
img {
border-radius: 50%;
}
}
}