Skip to content
This repository has been archived by the owner on May 13, 2024. It is now read-only.

Commit

Permalink
feat: carding internal implementation (#8)
Browse files Browse the repository at this point in the history
Breaking Changes:

Rename 'pagination.perPagePosts' to 'pagination.lengthPerPage'
  • Loading branch information
ulivz authored Jun 13, 2019
1 parent 7a28abf commit b249e86
Show file tree
Hide file tree
Showing 18 changed files with 673 additions and 324 deletions.
3 changes: 3 additions & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ module.exports = {
description: 'Offical blog plugin for VuePress',
themeConfig: {
repo: 'ulivz/vuepress-plugin-blog',
nav: [
{ text: 'Config', link: '/config/' }
]
}
}

151 changes: 71 additions & 80 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ sidebar: auto

# @vuepress/plugin-blog

> Official blog plugin for VuePress.
> Official blog plugin for VuePress.
Note that this plugin has been deeply integrated into [@vuepress/theme-blog](https://github.com/ulivz/vuepress-theme-blog).

Expand All @@ -19,7 +19,12 @@ yarn add -D @vuepress/plugin-blog

```javascript
module.exports = {
plugins: ['@vuepress/blog', { /* options */ }]
plugins: [
'@vuepress/blog',
{
/* options */
},
],
// Please keep looking down to see the available options.
}
```
Expand All @@ -31,25 +36,22 @@ module.exports = {
`Document classifier` is a set of functions that can classify pages with the same characteristics. For a blog developer, the same characteristics may exist between different pages as follows:

- Pages put in a directory (e.g. `_post`)
- Pages containing the same specific frontmatter key value (e.g. `tag: js`).
- Pages containing the same specific frontmatter key value (e.g. `tag: js`).

Of course, both of them may be related to another common
Of course, both of them may be related to another common
requirement, `pagination`.

So, how to combine them skillfully? Next, let's take a look at how this plugin solve these problems.


### Directory Classifier

Directory Classifier, that classifies the source pages placed in a same directory.

Suppose you have the following files structure:

``` vue
.
└── _posts
   ├── 2018-4-4-intro-to-vuepress.md
   └── 2019-6-8-intro-to-vuepress-next.md
```vue
. └── _posts    ├── 2018-4-4-intro-to-vuepress.md    └──
2019-6-8-intro-to-vuepress-next.md
```

In the traditional VuePress site, the converted page URLs will be:
Expand All @@ -63,33 +65,36 @@ It doesn't seem blogging, so it's time to use this plugin:
// .vuepress/config.js
module.exports = {
plugins: [
['@vuepress/blog', {
directories: [
{
// Unique ID of current classification
id: 'post',
// Target directory
dirname: '_posts',
// Path of the `entry page` (or `list page`)
path: '/',
},
],
}]
]
[
'@vuepress/blog',
{
directories: [
{
// Unique ID of current classification
id: 'post',
// Target directory
dirname: '_posts',
// Path of the `entry page` (or `list page`)
path: '/',
},
],
},
],
],
}
```

Then the plugin will help you to generate following pages, and automatically leverage corresponding
Then the plugin will help you to generate following pages, and automatically leverage corresponding
layout:

| url | layout |
|---|---|
| `/` | `IndexPost` / `Layout` |
| `/2018/04/04/intro-to-vuepress/` | `Post` |
| `/2019/06/08/intro-to-vuepress-next/` | `Post` |
| url | layout |
| ------------------------------------- | ---------------------- |
| `/` | `IndexPost` / `Layout` |
| `/2018/04/04/intro-to-vuepress/` | `Post` |
| `/2019/06/08/intro-to-vuepress-next/` | `Post` |

This means that you need to create two layout components(`IndexPost` and `Post`) to handle the layout of index and post
pages.
pages.

You can also custom the layout component name:

Expand Down Expand Up @@ -134,7 +139,7 @@ module.exports = {
```

::: warning
It is noteworthy that the `path` and `itemPermalink` must be uniformly modified, and `itemPermalink` must be prefixed with
It is noteworthy that the `path` and `itemPermalink` must be uniformly modified, and `itemPermalink` must be prefixed with
`path`.

The default value of `itemPermalink` is `'/:year/:month/:day/:slug'`.
Expand All @@ -143,8 +148,8 @@ The default value of `itemPermalink` is `'/:year/:month/:day/:slug'`.
### Pagination

As your blog articles grew more and more, you began to have the need for paging. By default, this plugin integrates a
very powerful pagination system that allows you to access paging functions with simple configuration.
very powerful pagination system that allows you to access paging functions with simple configuration.

By default, the plugin assumes that the max number of pages per page is `10`. you can also modify it like this:

```diff
Expand Down Expand Up @@ -175,23 +180,23 @@ Suppose you have 3 pages at `_posts` direcotry:

When the `perPagePosts` is set to `2`, this plugin will help you generate the following pages:

| url | layout |
|---|---|
| `/` | `IndexPost` / `Layout` |
| url | layout |
| ---------------- | -------------------------------- |
| `/` | `IndexPost` / `Layout` |
| `/page/2/` (New) | `DirectoryPagination` / `Layout` |
| `/2019/06/08/a/` | `Post` |
| `/2019/06/08/b/` | `Post` |
| `/2018/06/08/c/` | `Post` |
| `/2019/06/08/a/` | `Post` |
| `/2019/06/08/b/` | `Post` |
| `/2018/06/08/c/` | `Post` |

::: tip
::: tip
`DirectoryPagination / Layout` means that the layout component will be downgraded to `Layout` when `DirectoryPagination` layout doesn't exist.
:::
:::

So how to get the matched pages in the layout component? In fact, it will be much simpler than you think.

If you visit `/`, current page leverages layout `IndexPost`. In this layout component, you just need to use
`this.$pagination.pages` to get the matched pages. In the above example, the actual value of `this.$pagination.pages` will
be:
be:

```json
[
Expand All @@ -211,13 +216,11 @@ If you visit `/`, current page leverages layout `DirectoryPagination`, you can a

Isn't this very natural experience? You just need to care about the style of your layout component, not the complicated and boring logic behind it.


::: tip
To save the length of docs, we omitted the data structure of the `$page` object. You can get more information about
the data structure of `$page` at the [official documentation](https://v1.vuepress.vuejs.org/guide/global-computed.html#page).
:::


### Frontmatter Classifier

Frontmatter Classifier, which classifies pages that have the same frontmatter key values.
Expand Down Expand Up @@ -253,32 +256,35 @@ If you want to easily classify them, you can config like this:
```js
module.exports = {
plugins: [
['@vuepress/blog', {
frontmatters: [
{
// Unique ID of current classification
id: "tag",
// Decide that the frontmatter keys will be grouped under this classification
keys: ['tag'],
// Path of the `entry page` (or `list page`)
path: '/tag/',
// Layout of the `entry page`
layout: 'Tag',
},
]
}]
]
[
'@vuepress/blog',
{
frontmatters: [
{
// Unique ID of current classification
id: 'tag',
// Decide that the frontmatter keys will be grouped under this classification
keys: ['tag'],
// Path of the `entry page` (or `list page`)
path: '/tag/',
// Layout of the `entry page`
layout: 'Tag',
},
],
},
],
],
}
```

Then the plugin will help you to generate the following extra pages, and automatically leverage
the corresponding layout:

| url | layout |
|---|---|
| `/tag/` | `Tag` |
| url | layout |
| ----------- | ---------------------------------- |
| `/tag/` | `Tag` |
| `/tag/vue/` | `FrontmatterPagination` / `Layout` |
| `/tag/js/` | `FrontmatterPagination` / `Layout` |
| `/tag/js/` | `FrontmatterPagination` / `Layout` |

In the `Tags` component, you can use `this.$tag.list` to get the tag list. The value would be like:

Expand All @@ -302,9 +308,9 @@ In the `Tags` component, you can use `this.$tag.list` to get the tag list. The v
]
```

In the `FrontmatterPagination` component, you can use `this.$pagination.pages` to get the matched pages in current tag
In the `FrontmatterPagination` component, you can use `this.$pagination.pages` to get the matched pages in current tag
classification:

- If you visit `/tag/vue/`, the `this.$pagination.pages` will be:

```json
Expand All @@ -322,7 +328,6 @@ classification:
]
```


## Examples

Actually, there are only 2 necessary layout components to create a blog theme:
Expand All @@ -332,17 +337,3 @@ Actually, there are only 2 necessary layout components to create a blog theme:
- Tag (Only required when you set up a `tag` frontmatter classification.)

Here is [live example](https://github.com/ulivz/70-lines-of-vuepress-blog-theme) that implements a functionally qualified VuePress theme in around 70 lines.

## Options

### directories

> TODO, contribution welcome.
### frontmatters

> TODO, contribution welcome.



106 changes: 106 additions & 0 deletions docs/config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
sidebar: auto
---

# Config

## directories

- Type: `DirectoryClassifier[]`
- Default: `[]`

Create one or more [directory classifiers](../README.md#directory-classifier), all available options in
`DirectoryClassifier` are as
follows.

### id

- Type: `string`
- Default: `undefined`
- Required: `true`

Unique id for current classifier, e.g. `post`.

### dirname

- Type: `string`
- Default: `undefined`
- Required: `true`

Matched directory name, e.g. `_post`.

### path

- Type: `string`
- Default: `/${id}/`
- Required: `false`

Entry page for current classifier, e.g. `/` or `/post/`.

If you set `DirectoryClassifier.path` to `/`, it means that you want to access the matched pages list at `/`. set
to `/post/` is the same.

### layout

- Type: `string`
- Default: `'IndexPost' || 'Layout'`
- Required: `false`

Layout component name for entry page.

### frontmatter

- Type: `Record<string, any>`
- Default: `{}`
- Required: `false`

[Frontmatter](https://v1.vuepress.vuejs.org/guide/frontmatter.html) for entry page.

### itemLayout

- Type: `string`
- Default: `'Post'`
- Required: `false`

Layout for matched pages.

### itemPermalink

- Type: `string`
- Default: `'/:year/:month/:day/:slug'`
- Required: `false`

Permalink for matched pages.

For example, if you set up a directory classifier with dirname equals to `_post`, and have following pages:

```
.
└── _posts
├── 2018-4-4-intro-to-vuepress.md
└── 2019-6-8-intro-to-vuepress-next.md
```

With the default `itemPermalink`, you'll get following output paths:

```
/2018/04/04/intro-to-vuepress/
/2019/06/08/intro-to-vuepress-next/
```

For more details about permalinks, please head to [Permalinks](https://v1.vuepress.vuejs.org/guide/permalinks.html) section at VuePress's documentation.

### pagination

- Type: `Pagination`
- Default: `{ perPagePosts: 10 }`
- Required: `false`

All available options of pagination are as follows:

- pagination.perPagePosts: Maximum number of posts per page.
- pagination.pagesSorter: Maximum number of posts per page.

## frontmatters

> TODO, contribution welcome.
Loading

0 comments on commit b249e86

Please sign in to comment.