Skip to content

Commit

Permalink
chore(website): add new post
Browse files Browse the repository at this point in the history
  • Loading branch information
egoist committed Apr 9, 2019
1 parent cb55e1e commit 0f65ca8
Show file tree
Hide file tree
Showing 16 changed files with 274 additions and 9 deletions.
1 change: 1 addition & 0 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"generate": "saber generate"
},
"dependencies": {
"date-fns": "^1.30.1",
"jump.js": "^1.0.2",
"markdown-it-footnote": "^3.0.1",
"nprogress": "^0.2.0",
Expand Down
106 changes: 106 additions & 0 deletions website/pages/_posts/saber/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: Introducing Saber
subtitle: Building static website with modern techs.
layout: post
date: 2019-04-09
---

It's been two months already since the first release of Saber, but this is the first time we actually introduce it officially (excluding the [Tutortial](../../tutorial/tutorial.md)).

<img src="./preview.png" alt="preview">

Saber is a tool for building static websites with modern web techs like webpack, Babel and Vue. Getting started developing an application of any size is as easy as executing `saber`.

To start using it, run inside a new directory with a `package.json`:

```bash
$ npm install saber -D
```

Populate `pages/index.md`:

```markdown
Hello __Saber__!
```

Add a script to the `package.json` like this:

```json
{
"scripts": {
"dev": "saber"
}
}
```

and run:

```bash
$ npm run dev
```

## Background

The reason why I'm building Saber is simple: I love Hexo & Jekyll, but I also love using webpack & Vue, I enjoy the dev experience that you edit something and it automatically reflects in your browser, without refreshing.

Saber was previously known as [Peco](https://github.com/upash/peco) which is similar to _VuePress_ but also has the blog feature baked in. Saber is a complete rewrite that makes it possible to use data from anywhere, and it's not GraphQL based. Saber is designed to be simple, for Hexo / N[eu]xt.js users, it's is even easier to get started with.

## A small framework

We want to keep the core of Saber as flexible/small as possible:

<img src="./size-compare.png" alt="size compare" width="500">

Our goal is to make Saber smaller than 50 MB.

## Zero setup. Filesystem is the routing API.

Sometimes convention over configuration is a good practice, for example, Saber uses the filesystem as the routing API, you can populate `pages/index.md` which maps to the route `/` with:

```markdown
Hello __world__!
```

and then `pages/about.vue` which maps to `/about.html` with:

```vue
<template>
<h2>About us</h2>
</template>
```

All that's needed to start working on the project is to run:

```bash
$ saber
```

No configuration unless it's needed. Automatic hot-code reloading, error reporting, source maps, transpilation for older browsers.

## Blogging, Layouts & Theming

Just like Hexo, Saber uses `pages/_posts` folder for blog posts. If you populate a page at `pages/_posts/hello-world.md`, it will automatically map to `/posts/hello-world.html`.

Saber has all the plugins that're required for building a blog:

- If you want to display post list on your homepage, you can use [saber-plugin-query-post](https://github.com/egoist/saber/tree/master/packages/saber-plugin-query-posts) which also automatically generates _tag_ and _category_ pages.
- If you want RSS feed, use [saber-plugin-generate-feed](https://github.com/egoist/saber/tree/master/packages/saber-plugin-generate-feed).
- Find more at [awesome-saber](https://github.com/egoist/awesome-saber) or build your own!

Check out the tutorial [Intro the Saber](http://localhost:3000/tutorial/tutorial.html) to learn how to build a simple blog, use layouts, and share your layouts as a theme.

## Performance matters

It's wrong if it's not fast, a static website should be fast by default, but JavaScript slows it down.

The JavaScript runtime of Saber is around 40 KB minified and gzipped.

Every page inside `./pages` folder gets code splitting and their styles are inlined in the HTML.

Saber's `<saber-link>` (a drop-in replacement for Vue Router's `<router-link>`) will also prefetch the page component when user scrolls it into viewport.

For local development performance, Saber offers the Lazy Page Compilation mode which only compiles your pages when they are requested. This feature is experimental so we don't enable it by default, you can manually enable it via CLI flag `--lazy`.

---

In closing, this is my solution to building static websites with modern techs, if you like my work, please consider contributing to the project on [GitHub](https://github.com/egoist/saber), or supporting me on [Patreon](https://patreon.com/egoist)!
Binary file added website/pages/_posts/saber/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added website/pages/_posts/saber/size-compare.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions website/pages/blog/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
injectAllPosts: true
layout: index
title: Blog
---
1 change: 0 additions & 1 deletion website/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

<script>
export const attributes = {
title: 'Saber',
layout: 'index'
}
Expand Down
2 changes: 1 addition & 1 deletion website/pages/tutorial/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ yarn add saber-plugin-query-posts

Create a `saber-config.yml` to use this plugin:

```yml
```yaml
plugins:
- resolve: saber-plugin-query-posts
```
Expand Down
7 changes: 7 additions & 0 deletions website/saber-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ markdown:
plugins:
- resolve: markdown-it-footnote

build:
lazy: true

permalinks:
post: /blog/:slug.html

themeConfig:
sidebar:
- title: Basics
Expand Down Expand Up @@ -48,3 +54,4 @@ plugins:
- resolve: ../packages/saber-plugin-google-analytics
options:
trackId: UA-54857209-16
- resolve: ../packages/saber-plugin-query-posts
3 changes: 3 additions & 0 deletions website/src/components/Header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
<li class="menu-item">
<saber-link to="/tutorial/tutorial.html">Tutorial</saber-link>
</li>
<li class="menu-item">
<saber-link to="/blog/">Blog</saber-link>
</li>
<li class="menu-item">
<a href="https://github.com/egoist/saber" target="_blank">GitHub</a>
</li>
Expand Down
42 changes: 42 additions & 0 deletions website/src/components/PostList.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<template>
<div class="posts">
<div class="post" v-for="post in posts" :key="post.attributes.permalink">
<h2 class="post-title">
<saber-link :to="post.attributes.permalink">{{ post.attributes.title }}</saber-link>
</h2>
<PostMeta :page="post" />
<div class="post-excerpt" v-html="post.attributes.excerpt"></div>
</div>
</div>
</template>

<script>
import PostMeta from './PostMeta.vue'
export default {
components: {
PostMeta
},
props: ['posts']
}
</script>

<style scoped>
.post-title {
margin: 0;
}
/deep/ .page-meta {
margin-top: 10px;
}
.post {
&:not(:last-child) {
border-bottom: 1px solid #f0f0f0;
padding-bottom: 20px;
margin-bottom: 20px;
}
}
</style>

26 changes: 26 additions & 0 deletions website/src/components/PostMeta.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<template>
<div class="page-meta">
<span class="page-date">
{{ format(new Date(page.attributes.createdAt), 'MMM DD, YYYY') }}
</span>
</div>
</template>

<script>
import format from 'date-fns/format'
export default {
props: ['page'],
methods: {
format
}
}
</script>

<style scoped>
.page-meta {
margin-top: 20px;
color: var(--text-light-color);
}
</style>
9 changes: 8 additions & 1 deletion website/src/css/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
--sidebar-bg: white;
--gray: #666;
--dark: #000;
--text-color: #4e5b6a;
--text-color: #333;
--text-light-color: #73849a;
}

Expand Down Expand Up @@ -90,3 +90,10 @@ hr.footnotes-sep {
.footnote-item >*:last-child {
margin-bottom: 0;
}

.saber-highlight {
font-size: .875rem;
background-color: white;
border: 1px solid #f0f0f0;
border-radius: 0;
}
3 changes: 1 addition & 2 deletions website/src/css/page.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@
line-height: 1.6;
margin: 20px 0;

& >p:first-child {
& >*:first-child {
margin-top: 0;
font-size: 1.2rem;
}

& h2,
Expand Down
12 changes: 8 additions & 4 deletions website/src/layouts/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,32 @@
<Sidebar class="home-sidebar" :items="$themeConfig.sidebar"/>
<div class="content">
<main class="main">
<slot name="default" />
</main>
<slot name="default"/>
<PostList :posts="page.posts" />
</main>
</div>
</div>
</template>

<script>
import Header from '../components/Header.vue'
import Sidebar from '../components/Sidebar.vue'
import PostList from '../components/PostList.vue'
export default {
props: ['page'],
head() {
const { title } = this.page.attributes
return {
title: this.page.attributes.title
title: title ? `${title} - ${this.$siteConfig.title}` : this.$siteConfig.title
}
},
components: {
Header,
Sidebar
Sidebar,
PostList
}
}
</script>
Expand Down
61 changes: 61 additions & 0 deletions website/src/layouts/post.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<template>
<div class="layout">
<Header :showToggle="true"/>
<Sidebar class="home-sidebar" :items="$themeConfig.sidebar"/>
<div class="content">
<main class="main">
<h1 class="page-title">{{ page.attributes.title }}</h1>
<PostMeta :page="page" />
<div class="page-content">
<slot name="default"/>
</div>
</main>
</div>
</div>
</template>

<script>
import Header from '../components/Header.vue'
import Sidebar from '../components/Sidebar.vue'
import PostMeta from '../components/PostMeta.vue'
export default {
props: ['page'],
head() {
return {
title: `${this.page.attributes.title} - ${this.$siteConfig.title}`,
meta: [
{
name: 'twitter:title',
content: this.page.attributes.title
},
{
name: 'twitter:description',
content: this.page.attributes.subtitle
}
]
}
},
components: {
Header,
Sidebar,
PostMeta
}
}
</script>

<style scoped>
.home-sidebar {
display: none;
@media (max-width: 768px) {
display: block;
}
}
.page-title {
font-size: 3rem;
margin: 0;
}
</style>
5 changes: 5 additions & 0 deletions website/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ cssesc@^2.0.0:
resolved "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703"
integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==

date-fns@^1.30.1:
version "1.30.1"
resolved "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==

delegate@^3.1.2:
version "3.2.0"
resolved "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
Expand Down

0 comments on commit 0f65ca8

Please sign in to comment.