GithubHelp home page GithubHelp logo

saberland / saber Goto Github PK

View Code? Open in Web Editor NEW
2.1K 39.0 115.0 8.29 MB

()==[:::::::::::::> Build static sites in Vue.js, without the hassle

Home Page: https://saber.egoist.dev

License: MIT License

JavaScript 61.95% Vue 16.65% CSS 3.65% HTML 0.03% TypeScript 17.66% Pug 0.06%
static-site-generator vue blog-aware simple-yet-powerful

saber's Introduction

Saber

A static website generator built on top of Vue.js and webpack.

โค๏ธ Please sponsor me to support this project or prioritize a feature you want. I will work on this project for full-time once I have 150+ sponsors.

Linux & Mac Windows
CircleCI Should work

๐Ÿ”— Website

๐Ÿ“š Documentation

๐Ÿ‘ฉโ€๐Ÿซ Tutorial


Saber is an open source project. It's an independent project with its ongoing development made possible thanks to the support by our amazing backers.

Saber wouldn't be what it is today without the contributions from these awesome people:

contributors


Sponsors

Vercel


Licensed under MIT.

saber's People

Contributors

0xinhua avatar andreasvirkus avatar apostolique avatar chawyehsu avatar codebender828 avatar dependabot-preview[bot] avatar dependabot[bot] avatar dmarby avatar egoist avatar gavinmcfarland avatar h404bi avatar imyelo avatar ir1d avatar itsnickbarry avatar jamesgeorge007 avatar kidonng avatar krmax44 avatar lubien avatar matt-auckland avatar maxgfeller avatar meteorlxy avatar nblthree avatar renovate[bot] avatar rishi-raj-jain avatar saltysugar avatar samcx avatar spekulatius avatar spytec avatar triptych avatar vivekimsit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

saber's Issues

Pass route params to async data?

Is this possible (like in Nuxt), or am I doing it wrong? Trying to accomplish something like this:

// pages/[id].vue

<template>
  <div>
    <div>Post {{ id }}</div>
    <pre>{{ post }}</pre>
  </div>
</template>

<saber>
import axios from 'axios'

export default {
  params() {
    return {
      id: this.params.id // or this.$route.params.id ??
    }
  },

  async data() {
    const { data: post } = await axios
      .get(`https://jsonplaceholder.typicode.com/posts/${this.$route.params.id}`)
    return {
      post
    }
  }
}
</saber>

Getting the following error

image

It looks like in the Docs you're providing a hard coded array of params.

Serve static files

Serve static files under root path.

  • Serve static folder or public folder?
  • Serve $theme/$staticFolder as well?

Are we able to use <router-view />?

I would like the different routes to be setup within a router-view in the /pages/index.vue component. I created a new Vue project with the vue-cli with the vue router added.

For instance:
`

Welcome to saber.js
About

      <p>Lorem ipsum dolor</p>

      <router-view />
   </div>
</template>

`

When "About" is clicked, it doesn't show the about.vue component in that area of the template -- "Welcome to sabjer.js" the about link and paragraph are lost.

Is it possible to nest these components in a specific area of the template?

Thanks..

cannot resolve external script tag in markdown file

log:

ERROR in C:/workspace/website/pages/_posts/2019-03-27-saber-post.md?saberPage=86732c46
Module not found: Error: Can't resolve 'https://gist.github.com/h404bi/62f65347d5784b37c8535aa371c59720.js?vue&type=script&lang=js&saberPage=86732c46' in 'C:\workspace\website\pages\_posts'
 @ C:/workspace/website/pages/_posts/2019-03-27-saber-post.md?saberPage=86732c46 2:0-130 3:0-125 3:0-125 9:2-8
 @ C:/workspace/website/.saber/routes.js
 @ C:/workspace/website/node_modules/saber/lib/renderer/app/create-app.js
 @ C:/workspace/website/node_modules/saber/lib/renderer/app/entry-client.js
 @ multi (webpack)-hot-middleware/client.js C:/workspace/website/node_modules/saber/lib/renderer/app/entry-client.js

./pages/_posts/2019-03-27-saber-post.md:

---
layout: post
title: Hello Saber
date: 2019-03-27
---

Hello Saber!

<script src="https://gist.github.com/h404bi/62f65347d5784b37c8535aa371c59720.js"></script>

expose tag/category permalink from query-post plugin

Feature request

Expose/Return the permalink of tags or cateogries from the query-post plugin.

What problem does this feature solve?

So users or theme developers can use the permalink in their theme. Currently the only way to do it is by hardcoding the permalink in the theme. For instance:

https://github.com/egoist/blog/blob/b29939c7148e19b32b3020499b27ae29cea0cdf6/themes/luna/layouts/default.vue#L21

However, the permalinks of tags or categories can be dynamically configured by the plugin's option, which means it's independent of the theme. Let's suppose that one user install a compiled theme which contains hardcoded tags/categories support, then the user changes the permalinks format of tags or categories but does not (want to) change the hardcoded permalink format in the compiled theme. Then he/she will encouter problem on routing to tag or category pages.

What does the proposed API look like?

First idea comes to my mind is attaching permalink to the tag or category.

How should this be implemented in your opinion?

That's so useful if we could access the permalink of a tag/category directly.

<div class="tags" v-if="tags">
    <saber-link class="tag" :to="`${tag.permalink}`" v-for="tag in tags" :key="tag">
         #{{ tag }}
    </saber-link>

Are you willing to work on this yourself?

I'm not sure..

saber build hangs

Sometimes stuck in 95% emitting

...
info emitRoutes (vue-renderer)
info chainWebpack (vue-renderer)
info chainWebpack (builtin:config-css)
info chainWebpack (builtin:config-image)
info chainWebpack (builtin:config-font)
info chainWebpack (builtin:config-other-loaders)
info chainWebpack (google-analytics)
info chainWebpack (vue-renderer)
info chainWebpack (builtin:config-css)
info chainWebpack (builtin:config-image)
info chainWebpack (builtin:config-font)
info chainWebpack (builtin:config-other-loaders)
info chainWebpack (google-analytics)
Built at: 2019-03-30 10:25:27
Entrypoint server = js/server.563af2bf.js
success Compiled server successfully in 11.1s!
\ 95.00% emitting vue-client-plugin

Sometimes hangs after compile/build

...
info beforeRun (builtin:emit-saber-variables)
info defineVariables (generate-feed)
info emitRoutes (vue-renderer)
info chainWebpack (vue-renderer)
info chainWebpack (builtin:config-css)
info chainWebpack (builtin:config-image)
info chainWebpack (builtin:config-font)
info chainWebpack (builtin:config-other-loaders)
info chainWebpack (google-analytics)
info chainWebpack (vue-renderer)
info chainWebpack (builtin:config-css)
info chainWebpack (builtin:config-image)
info chainWebpack (builtin:config-font)
info chainWebpack (builtin:config-other-loaders)
info chainWebpack (google-analytics)
success Compiled server successfully in 9.1s!
# hangs

Feedback for --lazy mode

Saber 0.4 introduced --lazy mode which only compiles the page when it's requested (which will improve the build speed a lot), you can help us improve this feature by giving feedback!

Nested routes issue?

if I create pages like the nested pages example:

โ””โ”€โ”€ pages
    โ”œโ”€โ”€ index.vue
    โ”œโ”€โ”€ users
    โ”‚   โ”œโ”€โ”€ [name].vue
    โ”‚   โ””โ”€โ”€ index.vue # required
    โ””โ”€โ”€ users.vue     # required

then nothing under /users will load, instead I only see the users.vue page content.

if I remove the users/index.vue file, nested pages load properly.

Pug support

I added pug and pug-loader packages, but unlike Vuepress this didn't enable Pug templating. What can I do?

Fetching data demo not working

Hey @egoist ๐Ÿ‘‹. I see you've made another lib ha!! I was trying out the fetching data snippet and getting the following error:

image

My code is the same as in your example

<template>
  <div>{{ post.title }}</div>
</template>

<saber>
import axios from 'axios'

export default {
  async data() {
    const { data: post } = await axios
      .get('https://jsonplaceholder.typicode.com/posts/1')

    return {
      post
    }
  }
}
</saber>

Any thoughts?

[FEATURE] SPA style links?

Is it possible to do an SPA-style link such as <nuxt-link> or <router-link> ... or is Saber meant to be used with regular anchor tags?

Comparison with Nuxt.js / VuePress / Peco

Nuxt.js

data-prefetching

In Nuxt.js the data is pre-fetched at runtime, on both server-side and client-side. While in Saber.js the data is pre-fetched at compile time only, which in most cases is better for static websites.

simplicity

There's a big list of options in Nuxt.js, it makes sense since Nuxt.js is a versatile framework. But Saber.js is only targeting static websites, this would dramatically decrease the complexity of both maintaining this project and writing actual app code.

webpack-chain

The webpack config manager that vue-cli 3 and Poi use under the hood.

This doesn't matter that much, Nuxt.js could switch to it too if they want.

Dynamic routes

In Nuxt.js you use generate.routes to get actual URLs for dynamic routes like /user/:id, but in Saber.js it's done differently.

..etc

VuePress

Saber.js and VuePress almost works in the same way, (well every Vue static website generator works in the same way), except that Saber.js does not enforce a theme system that VuePress uses, which means Saber.js is better for building application.

data-prefetching

Not supported for now since VuePress uses local markdown files as source data.

Peco

Peco is something else.. It's like VuePress and Saber.js had a baby. It's more complex and currently in beta. (as a Gatsby.js alternative)

script tags appear to break HMR/Hot Reloading when included in md file?

What

Inserting script tags into an md file seems to break HMR*

Expected

HMR should work and pages should update without manual refresh

Reality

HMR does not work and pages do not auto-update.

Replicating

Create a page with:

# Title

## Subtitles

<script>console.log('I am alive')</script>

You will see the console.log message...

Try changing the markdown whilst the script tag remains... it won't update the page. Remove the script tag and HMR kicks in again and things start updating... curiously, if you change the console.log message, that does update the console.log message without refresh... but still not the page ๐Ÿ˜„

MBP 15" 2018, Latest macOS, latest Firefox...
Node: 10.14.1
NPM: 6.4.1

*if scripts are to be supported, this needs fixing... else all scripts need removing during compile/build and docs updating so say "no script support" or whatever?

Add layout transitions

I'd like to propose the ability to define page transitions also in layouts, as it becomes repetitive to set the same transition for every page of one type over and over again. Pages would then inherit the transition from their layout, similarly to how head currently works, with the possibility of overwriting it page-specifically, if needed.

Nesting category error

categories:
  - sports/football
ERROR in <omitted>/.saber/pages/internal_blog__category__sports/football.saberpage
Module build failed (from <omitted>/node_modules/saber/lib/renderer/saber-page-loader.js):
TypeError: Cannot read property 'hoistedTags' of undefined
    at Object.module.exports (<omitted>\node_modules\saber\lib\renderer\saber-page-loader.js:24:19)
 @ <omitted>/.saber/routes.js 250:11-252:70
 @ <omitted>/node_modules/saber/lib/renderer/app/create-app.js
 @ <omitted>/node_modules/saber/lib/renderer/app/entry-client.js
 @ multi (webpack)-hot-middleware/client.js <omitted>/node_modules/saber/lib/renderer/app/entry-client.js

Renaming/deleting markdown file breaks reloading

Issuehunt badges

Version

0.4.3

Steps to reproduce

  1. run dev server
  2. rename or delete a markdown file

What is expected?

Should handle renaming or deletion like Hexo, without breaking the workflow.

What is actually happening?

ERROR in <omitted>/pages/drafts/break.md?saberPage=61d9a790
Module build failed (from <omitted>/node_modules/saber/vue-renderer/lib/saber-page-loader.js):
Error: ENOENT: no such file or directory, open '<omitted>\pages\drafts\break.md'
...

marchworks earned $10.00 by resolving this issue!

Prefetching links in viewport

  1. check all links in view port
  2. if the link is a route path, we use <link rel="prefetch"> to prefetch the route component.

Template localization

I'd like to support different language mutations for my website. Urls would have a domain.com/{lang}/{page} format.

How should I achieve this with Saber.js, if I want to have the pages generated statically?

Generated router.js in windows

In Windows, the separator of the generated file becomes a backslash and an error occurs

export default [
  {
    path: '/',
    component: () => import(/* webpackChunkName: "page--index" */ '#pages/index.vue')
  }
  ,
  {
    path: '/users\index',
    component: () => import(/* webpackChunkName: "page--users-index" */ '#pages/users\index.vue')
  }
 ]

By rewriting it as follows, it works normally

export default [
  {
    path: '/',
    component: () => import(/* webpackChunkName: "page--index" */ '#pages/index.vue')
  }
  ,
  {
    path: '/users/index',
    component: () => import(/* webpackChunkName: "page--users-index" */ '#pages/users/index.vue')
  }
 ]

๐Ÿ˜ฅ #pages/users\index.vue -> ๐Ÿ˜„ #pages/users/index.vue

thank you

Only add page in .saber/routes.js when it's visited

By default in dev mode we should emit a routes.js exporting an empty array, when you visited a page in browser we add this page to routes.js and let browser wait until the build completes.

This should dramatically improve build performance ๐Ÿค”

Plugin for night mode like samsung internet night mode

Feature request

How should this be implemented in your opinion?

A plugin that generate new style from page style

Are you willing to work on this yourself?

Yes

So what do you think about this idea can it be implemented?

saber-node.js undefined error

Hello @egoist ,

I have published saber-theme-ume on npmjs.com, but I met an error when run npm run dev (It works well when I run npm run dev:example on the theme folder):

$ npm run dev

> @ dev /Users/cyris/Desktop/umeeee/my-blog-3
> saber

info Using theme: /Users/cyris/Desktop/umeeee/my-blog-3/node_modules/saber-theme-ume/dist
info afterPlugins (theme-node-api)
info afterPlugins (user-node-api)
info beforeRun (builtin:source-pages)
info initPages (theme-node-api)
info initPages (user-node-api)
info onCreatePages (query-posts)
info onCreatePages (theme-node-api)
error TypeError: Cannot read property 'type' of undefined
    at /Users/cyris/Desktop/umeeee/my-blog-3/node_modules/saber-theme-ume/dist/saber-node.js:4:28
    at Array.filter (<anonymous>)
    at Saber.exports.onCreatePages (/Users/cyris/Desktop/umeeee/my-blog-3/node_modules/saber-theme-ume/dist/saber-node.js:3:46)
    at tapInfo.fn.args (/Users/cyris/Desktop/umeeee/my-blog-3/node_modules/saber/lib/index.js:67:20)
    at Promise (eval at create (/Users/cyris/Desktop/umeeee/my-blog-3/node_modules/tapable/lib/HookCodeFactory.js:65:10), <anonymous>:25:1)
    at new Promise (<anonymous>)
    at AsyncSeriesHook.eval [as promise] (eval at create (/Users/cyris/Desktop/umeeee/my-blog-3/node_modules/tapable/lib/HookCodeFactory.js:65:10), <anonymous>:4:8)
    at AsyncSeriesHook.lazyCompileHook (/Users/cyris/Desktop/umeeee/my-blog-3/node_modules/tapable/lib/Hook.js:154:20)
    at api.hooks.beforeRun.tapPromise (/Users/cyris/Desktop/umeeee/my-blog-3/node_modules/saber/lib/plugins/source-pages.js:99:35)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! @ dev: `saber`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Is there something wrong with the saber-node.js file or I just I missed some steps when running it?

Images folder

I am trying to add a logo and cannot figure out where to put it. Iโ€™ve tried an assets, and a public folder in the root of my project, and under the theme.

Parse permalinks placeholders from markdown files name

Just like what Hexo does.

saber-config.yml

permalinks:
  post: /posts/:year/:month/:day/:slug.html

./pages/_posts/2019-03-24-hello-saber.md

---
layout: post
date: 2019-03-24
---

Expect:

./pages/_posts/2019-03-24-hello-saber.md becomes /posts/2019/03/24/hello-saber.html

Actual:

./pages/_posts/2019-03-24-hello-saber.md becomes /posts/2019/03/24/2019-03-24-hello-saber.html

Is there a possible way to separate the metadata configuration to re-use in all components?

Hello. I'm trying to separate the metadata config (head object indicated here ), but it seems that it cannot be possible because can't find the module at its actual path.

File: _shared/metadata.js

const HeadMetadata = {
	title: "Personal portfolio",
	meta: [
		{ name: "msapplication-TileColor", content: "#ffffff" }
		{ name: "msapplication-TileImage", content: "../assets/favicon/ms-icon-144x144.png" }
		{ name: "theme-color", content: "#ffffff" }
	],
	link: [
		{ rel: "apple-touch-icon", sizes: "57x57", href: "../assets/favicon/apple-icon-57x57.png" },
		{ rel: "apple-touch-icon", sizes: "60x60", href: "../assets/favicon/apple-icon-60x60.png" },
		{ rel: "apple-touch-icon", sizes: "72x72", href: "../assets/favicon/apple-icon-72x72.png" },
		{ rel: "apple-touch-icon", sizes: "76x76", href: "../assets/favicon/apple-icon-76x76.png" },
		{ rel: "apple-touch-icon", sizes: "114x114", href: "../assets/favicon/apple-icon-114x114.png" },
		{ rel: "apple-touch-icon", sizes: "120x120", href: "../assets/favicon/apple-icon-120x120.png" },
		{ rel: "apple-touch-icon", sizes: "144x144", href: "../assets/favicon/apple-icon-144x144.png" },
		{ rel: "apple-touch-icon", sizes: "152x152", href: "../assets/favicon/apple-icon-152x152.png" },
		{ rel: "apple-touch-icon", sizes: "180x180", href: "../assets/favicon/apple-icon-180x180.png" },
		{ rel: "icon", type: "image/png", sizes: "192x192", href: "../assets/favicon/android-icon-192x192.png" },
		{ rel: "icon", type: "image/png", sizes: "32x32", href: "../assets/favicon/favicon-32x32.png" },
		{ rel: "icon", type: "image/png", sizes: "96x96", href: "../assets/favicon/favicon-96x96.png" },
		{ rel: "icon", type: "image/png", sizes: "16x16", href: "../assets/favicon/favicon-16x16.png" },
		{ rel: "manifest", href: "/manifest.json" }
	]
}
module.exports = HeadMetadata;

But, when I try to import to some Vue file in pages says "Module not found. Can't resolve _shared/metadata.js".

Broken on Windows

$ yarn create blog demo
...
$ yarn dev
yarn run v1.13.0
$ saber
Built at: 2019-03-09 15:03:40
Entrypoint client [big] = js/client.js js/client.js.map

ERROR in ./pages/about.vue?vue&type=custom&index=0&blockType=extend-component&saberPage=7291c502 (./node_modules/saber/lib/renderer/extend-component-loader.js!./node_modules/vue-loader/lib??vue-loader-options!./node_modules/saber/lib/renderer/saber-page-loader.js??ref--2-1!./pages/about.vue?vue&type=custom&index=0&blockType=extend-component&saberPage=7291c502)
Module not found: Error: Can't resolve 'C:Usershanabi   mpdemopagesabout.vue' in 'C:\Users\hanabi\tmp\demo\pages'
 @ ./pages/about.vue?vue&type=custom&index=0&blockType=extend-component&saberPage=7291c502 (./node_modules/saber/lib/renderer/extend-component-loader.js!./node_modules/vue-loader/lib??vue-loader-options!./node_modules/saber/lib/renderer/saber-page-loader.js??ref--2-1!./pages/about.vue?vue&type=custom&index=0&blockType=extend-component&saberPage=7291c502) 7:0-68 11:17-30
 @ ./pages/about.vue?vue&type=custom&index=0&blockType=extend-component&saberPage=7291c502
 @ ./pages/about.vue?saberPage=7291c502
 @ ./.saber/routes.js
 @ ./node_modules/saber/lib/renderer/app/create-app.js
 @ ./node_modules/saber/lib/renderer/app/entry-client.js
 @ multi (webpack)-hot-middleware/client.js ./node_modules/saber/lib/renderer/app/entry-client.js

New docs

The new docs (https://saberjs.org/) is WIP, let me know if anything important is missing, or something you'd like to see in the docs.

Redirect support

Motivation

Sometimes you might change the permalink of a page, e.g. move /about to /about-us but you don't want to break existing links to /about

Solution

Add a new api in saber-browser.js:

export default ({ addRedirect }) => {
  addRedirect({
    from: '/about',
    to: '/about-us'
  })
}

Implementation

In dev mode, we can simply add a redirect route in vue-router's routes option, in production mode, we also need to generate about/index.html with only <meta http-equiv="refresh" content="0;url=/about-us" /> to redirect the page on first visit.

Support `:categories` in permalinks template

Like the similar feature in Jekyll:

If a post has multiple categories, Jekyll will create a hierarchy (e.g. /category1/category2). Also Jekyll automatically parses out double slashes in the URLs, so if no categories are present, it will ignore this.

Inject markdown headers as page attributes

Issuehunt badges

Add a markdown-it plugin to inject markdown headers [{ text: 'Hello', slug: hello' }] as page.attributes.markdownHeaders, similar to Vuepress's this.$page.headers.

When to inject:

  • page.attributes.injectMarkdownHeaders === true
  • Or page.attributes.injectMarkdownHeaders !== false && api.config.markdown.injectMarkdownHeaders

The injected markdown headers can be used by https://github.com/egoist/saber/pull/49

krmax44 earned $60.00 by resolving this issue!

Related posts support

Hello @egoist,

Recently I'm making a theme based on saber, and I want to add related posts function to post pages (e.g. next post, pre post). I didn't find it on the docs, will Saber.js support it in the future? :D

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.