Browse Source

Add Blogo post

master
arnaucube 7 years ago
parent
commit
f6cc0a4cb7
16 changed files with 814 additions and 0 deletions
  1. +19
    -0
      blogo-input/blogo.json
  2. +11
    -0
      blogo-input/css/style.css
  3. BIN
      blogo-input/img/email.png
  4. BIN
      blogo-input/img/gradient-background-2560x1600.jpg
  5. BIN
      blogo-input/img/logoArnauCube.png
  6. BIN
      blogo-input/img/logoArnauCubeFavicon.png
  7. BIN
      blogo-input/img/logoArnauCubeTransparent.png
  8. BIN
      blogo-input/img/posts/blogo/go-logo.png
  9. +35
    -0
      blogo-input/js/external-links.js
  10. +96
    -0
      blogo-input/js/highlightjs/atom-one-dark.css
  11. +108
    -0
      blogo-input/js/highlightjs/gruvbox-dark.css
  12. +108
    -0
      blogo-input/js/highlightjs/gruvbox-light.css
  13. +2
    -0
      blogo-input/js/highlightjs/highlight.pack.js
  14. +83
    -0
      blogo-input/js/highlightjs/monokai-sublime.css
  15. +348
    -0
      blogo-input/posts/blogo.md
  16. +4
    -0
      blogo-input/posts/blogo_thumb.md

+ 19
- 0
blogo-input/blogo.json

@ -0,0 +1,19 @@
{
"title": "ArnauCube - Blog",
"relativePath": "/blog",
"postsDir": "posts",
"indexTemplate": "index.html",
"postThumbTemplate": "postThumbTemplate.html",
"posts": [
{
"thumb": "blogo_thumb.md",
"md": "blogo.md"
}
],
"copyRaw": [
"css",
"img",
"vendor",
"js"
]
}

+ 11
- 0
blogo-input/css/style.css

@ -0,0 +1,11 @@
.o_gradient_background{
background-color: #222222;
background-image: url('../img/gradient-background-2560x1600.jpg');
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
}
a {
text-decoration:none!important;
}

BIN
blogo-input/img/email.png

Before After
Width: 171  |  Height: 33  |  Size: 2.7 KiB

BIN
blogo-input/img/gradient-background-2560x1600.jpg

Before After
Width: 2560  |  Height: 1600  |  Size: 251 KiB

BIN
blogo-input/img/logoArnauCube.png

Before After
Width: 800  |  Height: 800  |  Size: 177 KiB

BIN
blogo-input/img/logoArnauCubeFavicon.png

Before After
Width: 150  |  Height: 150  |  Size: 16 KiB

BIN
blogo-input/img/logoArnauCubeTransparent.png

Before After
Width: 800  |  Height: 800  |  Size: 177 KiB

BIN
blogo-input/img/posts/blogo/go-logo.png

Before After
Width: 1634  |  Height: 2224  |  Size: 111 KiB

+ 35
- 0
blogo-input/js/external-links.js

@ -0,0 +1,35 @@
// Works like jQuery's $(document).ready.
// Supports IE8+. Courtesy of http://youmightnotneedjquery.com/
function ready(fn) {
if (document.readyState != 'loading') {
fn();
} else if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', fn);
} else {
document.attachEvent('onreadystatechange', function() {
if (document.readyState != 'loading')
fn();
});
}
}
ready(function() {
var website = window.location.hostname;
var internalLinkRegex = new RegExp('^((((http:\\/\\/|https:\\/\\/)(www\\.)?)?'
+ website
+ ')|(localhost:\\d{4})|(\\/.*))(\\/.*)?$', '');
var anchorEls = document.querySelectorAll('a');
var anchorElsLength = anchorEls.length;
for (var i = 0; i < anchorElsLength; i++) {
var anchorEl = anchorEls[i];
var href = anchorEl.getAttribute('href');
if (!internalLinkRegex.test(href)) {
anchorEl.setAttribute('target', '_blank');
}
}
});

+ 96
- 0
blogo-input/js/highlightjs/atom-one-dark.css

@ -0,0 +1,96 @@
/*
Atom One Dark by Daniel Gamage
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
base: #282c34
mono-1: #abb2bf
mono-2: #818896
mono-3: #5c6370
hue-1: #56b6c2
hue-2: #61aeee
hue-3: #c678dd
hue-4: #98c379
hue-5: #e06c75
hue-5-2: #be5046
hue-6: #d19a66
hue-6-2: #e6c07b
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #abb2bf;
background: #282c34;
}
.hljs-comment,
.hljs-quote {
color: #5c6370;
font-style: italic;
}
.hljs-doctag,
.hljs-keyword,
.hljs-formula {
color: #c678dd;
}
.hljs-section,
.hljs-name,
.hljs-selector-tag,
.hljs-deletion,
.hljs-subst {
color: #e06c75;
}
.hljs-literal {
color: #56b6c2;
}
.hljs-string,
.hljs-regexp,
.hljs-addition,
.hljs-attribute,
.hljs-meta-string {
color: #98c379;
}
.hljs-built_in,
.hljs-class .hljs-title {
color: #e6c07b;
}
.hljs-attr,
.hljs-variable,
.hljs-template-variable,
.hljs-type,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-number {
color: #d19a66;
}
.hljs-symbol,
.hljs-bullet,
.hljs-link,
.hljs-meta,
.hljs-selector-id,
.hljs-title {
color: #61aeee;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-link {
text-decoration: underline;
}

+ 108
- 0
blogo-input/js/highlightjs/gruvbox-dark.css

@ -0,0 +1,108 @@
/*
Gruvbox style (dark) (c) Pavel Pertsev (original style at https://github.com/morhetz/gruvbox)
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #282828;
}
.hljs,
.hljs-subst {
color: #ebdbb2;
}
/* Gruvbox Red */
.hljs-deletion,
.hljs-formula,
.hljs-keyword,
.hljs-link,
.hljs-selector-tag {
color: #fb4934;
}
/* Gruvbox Blue */
.hljs-built_in,
.hljs-emphasis,
.hljs-name,
.hljs-quote,
.hljs-strong,
.hljs-title,
.hljs-variable {
color: #83a598;
}
/* Gruvbox Yellow */
.hljs-attr,
.hljs-params,
.hljs-template-tag,
.hljs-type {
color: #fabd2f;
}
/* Gruvbox Purple */
.hljs-builtin-name,
.hljs-doctag,
.hljs-literal,
.hljs-number {
color: #8f3f71;
}
/* Gruvbox Orange */
.hljs-code,
.hljs-meta,
.hljs-regexp,
.hljs-selector-id,
.hljs-template-variable {
color: #fe8019;
}
/* Gruvbox Green */
.hljs-addition,
.hljs-meta-string,
.hljs-section,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-string,
.hljs-symbol {
color: #b8bb26;
}
/* Gruvbox Aqua */
.hljs-attribute,
.hljs-bullet,
.hljs-class,
.hljs-function,
.hljs-function .hljs-keyword,
.hljs-meta-keyword,
.hljs-selector-pseudo,
.hljs-tag {
color: #8ec07c;
}
/* Gruvbox Gray */
.hljs-comment {
color: #928374;
}
/* Gruvbox Purple */
.hljs-link_label,
.hljs-literal,
.hljs-number {
color: #d3869b;
}
.hljs-comment,
.hljs-emphasis {
font-style: italic;
}
.hljs-section,
.hljs-strong,
.hljs-tag {
font-weight: bold;
}

+ 108
- 0
blogo-input/js/highlightjs/gruvbox-light.css

@ -0,0 +1,108 @@
/*
Gruvbox style (light) (c) Pavel Pertsev (original style at https://github.com/morhetz/gruvbox)
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #fbf1c7;
}
.hljs,
.hljs-subst {
color: #3c3836;
}
/* Gruvbox Red */
.hljs-deletion,
.hljs-formula,
.hljs-keyword,
.hljs-link,
.hljs-selector-tag {
color: #9d0006;
}
/* Gruvbox Blue */
.hljs-built_in,
.hljs-emphasis,
.hljs-name,
.hljs-quote,
.hljs-strong,
.hljs-title,
.hljs-variable {
color: #076678;
}
/* Gruvbox Yellow */
.hljs-attr,
.hljs-params,
.hljs-template-tag,
.hljs-type {
color: #b57614;
}
/* Gruvbox Purple */
.hljs-builtin-name,
.hljs-doctag,
.hljs-literal,
.hljs-number {
color: #8f3f71;
}
/* Gruvbox Orange */
.hljs-code,
.hljs-meta,
.hljs-regexp,
.hljs-selector-id,
.hljs-template-variable {
color: #af3a03;
}
/* Gruvbox Green */
.hljs-addition,
.hljs-meta-string,
.hljs-section,
.hljs-selector-attr,
.hljs-selector-class,
.hljs-string,
.hljs-symbol {
color: #79740e;
}
/* Gruvbox Aqua */
.hljs-attribute,
.hljs-bullet,
.hljs-class,
.hljs-function,
.hljs-function .hljs-keyword,
.hljs-meta-keyword,
.hljs-selector-pseudo,
.hljs-tag {
color: #427b58;
}
/* Gruvbox Gray */
.hljs-comment {
color: #928374;
}
/* Gruvbox Purple */
.hljs-link_label,
.hljs-literal,
.hljs-number {
color: #8f3f71;
}
.hljs-comment,
.hljs-emphasis {
font-style: italic;
}
.hljs-section,
.hljs-strong,
.hljs-tag {
font-weight: bold;
}

+ 2
- 0
blogo-input/js/highlightjs/highlight.pack.js
File diff suppressed because it is too large
View File


+ 83
- 0
blogo-input/js/highlightjs/monokai-sublime.css

@ -0,0 +1,83 @@
/*
Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #23241f;
}
.hljs,
.hljs-tag,
.hljs-subst {
color: #f8f8f2;
}
.hljs-strong,
.hljs-emphasis {
color: #a8a8a2;
}
.hljs-bullet,
.hljs-quote,
.hljs-number,
.hljs-regexp,
.hljs-literal,
.hljs-link {
color: #ae81ff;
}
.hljs-code,
.hljs-title,
.hljs-section,
.hljs-selector-class {
color: #a6e22e;
}
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-name,
.hljs-attr {
color: #f92672;
}
.hljs-symbol,
.hljs-attribute {
color: #66d9ef;
}
.hljs-params,
.hljs-class .hljs-title {
color: #f8f8f2;
}
.hljs-string,
.hljs-type,
.hljs-built_in,
.hljs-builtin-name,
.hljs-selector-id,
.hljs-selector-attr,
.hljs-selector-pseudo,
.hljs-addition,
.hljs-variable,
.hljs-template-variable {
color: #e6db74;
}
.hljs-comment,
.hljs-deletion,
.hljs-meta {
color: #75715e;
}

+ 348
- 0
blogo-input/posts/blogo.md

@ -0,0 +1,348 @@
# Static blog template engine implementation in Go
*2017-12-26*
Some days ago, I decided to start this blog, to put there all the thoughts and ideas that goes through my mind. After some research, I've found some interesting projects, but with a lot of features that I don't need to use. So I decided to write my own minimalistic static blog template engine with Go lang.
This is how I made [blogo](https://github.com/arnaucube/blogo) the blog static template engine to do this blog.
### Static blog template engine?
The main idea is to be able to write the blog posts in Markdown files, and with the template engine, output the HTML files ready to upload in the web hosting server.
## Structure
What we wan to have in the input is:
```
/blogo
/input
/css
mycss.css
/img
post01_image.png
index.html
postThumbTemplate.html
post01.md
post01thumb.md
post02.md
post02thumb.md
```
#### blogo.json
This is the file that have the configuration that will be read by the Go script.
```json
{
"title": "my blog",
"indexTemplate": "index.html",
"postThumbTemplate": "postThumbTemplate.html",
"posts": [
{
"thumb": "post01thumb.md",
"md": "post01.md"
},
{
"thumb": "post02thumb.md",
"md": "post02.md"
}
],
"copyRaw": [
"css",
"js"
]
}
```
The *copyRaw* element, will be all the directories to copy raw to the output.
#### index.html
This is the file that will be used as the template for the main page and also for the posts pages.
```html
<!DOCTYPE html>
<html>
<head>
<title>[blogo-title]</title>
</head>
<body>
<div>
[blogo-content]
</div>
</body>
</html>
```
As we can see, we just need to define the html file, and in the title define the *[blogo-title]*, and in the content place the *[blogo-content]*.
#### postThumbTemplate.html
This is the file where is placed the html box for each post that will be displayed in the main page.
```html
<div class="well">
[blogo-index-post-template]
</div>
```
#### post01thumb.md
```markdown
# Post 01 thumb
This is the description of the Post 01
```
#### post01.md
```markdown
# Title of the Post 01
Hi, this is the content of the post
'''js
console.log("hello world");
'''
```
## Let's start to code
As we have exposed, we want to develop a Go lang script that from some HTML template and the Markdown text files, generates the complete blog with the main page and all the posts.
#### readConfig.go
This is the file that reads the *blogo.json* file to get the blog configuration.
```go
package main
import (
"encoding/json"
"io/ioutil"
)
//Post is the struct for each post of the blog
type Post struct {
Thumb string `json:"thumb"`
Md string `json:"md"`
}
//Config gets the config.json file into struct
type Config struct {
Title string `json:"title"`
IndexTemplate string `json:"indexTemplate"`
PostThumbTemplate string `json:"postThumbTemplate"`
Posts []Post `json:"posts"`
CopyRaw []string `json:"copyRaw"`
}
var config Config
func readConfig(path string) {
file, err := ioutil.ReadFile(path)
check(err)
content := string(file)
json.Unmarshal([]byte(content), &config)
}
```
#### files.go, the operations with files
We will need some file operation functions, so we have placed all in this file.
```go
package main
import (
"io/ioutil"
"os/exec"
"strings"
"github.com/fatih/color"
)
func readFile(path string) string {
dat, err := ioutil.ReadFile(path)
if err != nil {
color.Red(path)
}
check(err)
return string(dat)
}
func writeFile(path string, newContent string) {
err := ioutil.WriteFile(path, []byte(newContent), 0644)
check(err)
color.Green(path)
}
func getLines(text string) []string {
lines := strings.Split(text, "\n")
return lines
}
func concatStringsWithJumps(lines []string) string {
var r string
for _, l := range lines {
r = r + l + "\n"
}
return r
}
func copyRaw(original string, destination string) {
color.Green(original + " --> to --> " + destination)
_, err := exec.Command("cp", "-rf", original, destination).Output()
check(err)
}
```
#### main.go
To convert the HTML content to Markdown content, we will use https://github.com/russross/blackfriday
```go
package main
import (
"fmt"
"strings"
blackfriday "gopkg.in/russross/blackfriday.v2"
)
const directory = "blogo-input"
func main() {
readConfig(directory + "/blogo.json")
fmt.Println(config)
// generate index page
indexTemplate := readFile(directory + "/" + config.IndexTemplate)
indexPostTemplate := readFile(directory + "/" + config.PostThumbTemplate)
var blogoIndex string
blogoIndex = ""
for _, post := range config.Posts {
mdpostthumb := readFile(directory + "/" + post.Thumb)
htmlpostthumb := string(blackfriday.Run([]byte(mdpostthumb)))
//put the htmlpostthumb in the blogo-index-post-template
m := make(map[string]string)
m["[blogo-index-post-template]"] = htmlpostthumb
r := putHTMLToTemplate(indexPostTemplate, m)
filename := strings.Split(post.Md, ".")[0]
r = "<a href='" + filename + ".html'>" + r + "</a>"
blogoIndex = blogoIndex + r
}
//put the blogoIndex in the index.html
m := make(map[string]string)
m["[blogo-title]"] = config.Title
m["[blogo-content]"] = blogoIndex
r := putHTMLToTemplate(indexTemplate, m)
writeFile("index.html", r)
// generate posts pages
for _, post := range config.Posts {
mdcontent := readFile(directory + "/" + post.Md)
htmlcontent := string(blackfriday.Run([]byte(mdcontent)))
m := make(map[string]string)
m["[blogo-title]"] = config.Title
m["[blogo-content]"] = htmlcontent
r := putHTMLToTemplate(indexTemplate, m)
//fmt.Println(r)
filename := strings.Split(post.Md, ".")[0]
writeFile(filename+".html", r)
}
//copy raw
fmt.Println("copying raw:")
for _, dir := range config.CopyRaw {
copyRaw(directory+"/"+dir, ".")
}
}
func putHTMLToTemplate(template string, m map[string]string) string {
lines := getLines(template)
var resultL []string
for _, line := range lines {
inserted := false
for k, v := range m {
if strings.Contains(line, k) {
//in the line, change [tag] with the content
lineReplaced := strings.Replace(line, k, v, -1)
resultL = append(resultL, lineReplaced)
inserted = true
}
}
if inserted == false {
resultL = append(resultL, line)
}
}
result := concatStringsWithJumps(resultL)
return result
}
```
## Try it
To try it, we need to compile the Go code:
```
> go build
```
And run it:
```
> ./blogo
```
Or we can just build and run to test:
```
> go run *.go
```
As the output, we will obtain the html pages with the content:
- index.html
```html
<!DOCTYPE html>
<html>
<head>
<title>my blog</title>
</head>
<body>
<div class="row">
<a href='post01.html'>
<div class="col-md-3">
<h1>Post 01 thumb</h1>
<p>This is the description of the Post 01</p>
</div>
</a>
<a href='post02.html'>
<div class="col-md-3">
<p>Post 02 thumb</p>
</div>
</a>
</div>
</body>
</html>
```
- post01.html
```html
<!DOCTYPE html>
<html>
<head>
<title>my blog</title>
</head>
<body>
<div>
<h1>Title of the Post 01</h1>
<p>Hi, this is the content of the post</p>
<pre>
<code class="language-js"> console.log(&quot;hello world&quot;);
</code>
</pre>
</div>
</body>
</html>
```
## Conclusion
In this post, we have seen how to develop a very minimalistic static blog template engine with Go. In fact, is the blog engine that I'm using for this blog.
There are lots of blog template engines nowadays, but maybe we don't need sophisticated engine, and we just need a minimalistic one. In that case, we have seen how to develop one.
The complete project code is able in https://github.com/arnaucube/blogo

+ 4
- 0
blogo-input/posts/blogo_thumb.md

@ -0,0 +1,4 @@
## Static blog template engine implementation in Go
How has this blog been made? In this post we will see how to develop a minimalistic static blog template engine with Go.
*2017-12-26*

Loading…
Cancel
Save