vuejs / vuepress

πŸ“ Minimalistic Vue-powered static site generator
https://vuepress.vuejs.org
MIT License
22.49k stars 4.77k forks source link

Blog Support roadmap (Resolved) #36

Closed chuckdries closed 5 years ago

chuckdries commented 6 years ago

Hello,

I'm excited to use vuepress for my personal website but I kinda want blog support before I switch, so I was thinking I'd kickstart that discussion on that now. This issue is to seek input as to what blog support might look like.

I was thinking a minimum viable product might be

FadySamirSadek commented 6 years ago

I think you should add also the functionality to publish only posts with dates that has already came like gatsby and jekyll. If you need help I would absolutely love to work on these tasks with you

gaomd commented 6 years ago
mdaffin commented 6 years ago

The ability to alias posts and create redirects for them to allow movement of old posts while preserving all incoming links.

ch1nux commented 6 years ago

Maybe list all post in some sort of filter (customizable, of course), tags or categories and show them in README.md at first (chronologically or by tags).

Tsuki commented 6 years ago

vuepress eject with default config

lekevicius commented 6 years ago

I have been reading VuePress code and comparing with the blog build system I have written for Gulp.

List of features I have for my gulp static blog:

These are all the features I've built for gulp static site building, and would like VuePress to have.

However, adding all of that to the "core" would not be very great. I think a better, smarter solution would be to think of a way to allow themes to modify/plug into prepare and build stages, creating virtual pages, feed, etc.

I'm happy to help building and designing Blog theme, but I'd like to work out this build stage plugins before, instead of forking and modifying "core".

mdaffin commented 6 years ago

Looks like it is reasonably easy to get lists of posts and filter tags/categories working even without support in the Layouts. Inside any .md file:

---
home: true
---
<div v-for="post in posts_with_tag('some_tag')"
     :key="post.frontmatter.date">
  <router-link :to="post.path">
    <article>
      <div class="title">{{ post.title }}</div>
      <div class="date">{{ new Date(post.frontmatter.date).toLocaleDateString() }}</div>
      <div class="description">{{ post.frontmatter.description }}</div>
    </article>
  </router-link>
</div>

<script>
export default {
    methods: {
        posts_with_tag(tag) {
            return this.$site.pages
            .filter((page) => page.frontmatter.tags)
            .filter((page) => page.frontmatter.tags.includes(tag))
        },
        posts() {
            return this.$site.pages
            .filter((page) => page.path.startsWith("/blog/"))
        }
    },
}
</script>

The only missing part is being able to generate dynamic pages, but I think this can be solved generically along with creating a sitemap, rss feed, specific tag/category pages, redirect links by allowing the theme or pages to add extra routes with plain text content or layouts with data. With something like add_route(route, payload, layout) or add_route(route, content) that the layout/pages can call on the fly for example when they detect a new tag.

lekevicius commented 6 years ago

Quite right. Generic features/building blogs needed:

With these building blogs, entire blogging system can be made πŸŽ‰

mdaffin commented 6 years ago

@lekevicius I think those are the core features that are missing from vuepress, once those are added I believe that the rest of the features listed in this thread can be accomplished through the default or may be an alternitive them. It might be worth rasing them as seperate issues if the others agree?

GabMic commented 6 years ago

A draft outosave system.

yeedle commented 6 years ago

What about comments? A default theme should perhaps offer a commenting component that integrates one of the popular commenting platforms.

yyx990803 commented 6 years ago

So - the default theme is going to be focused on documentation sites. Proper blog support should be done in a separate theme - and we currently don't have the bandwidth to work on that, so the goal in VuePress core should be designing the minimum API that can enable a custom theme to provide full blogging support. I'd encourage the community to explore that and provide feedback on what is currently lacking (e.g. this comment) and what kind of APIs would make that possible.

For registering additional routes, currently .vuepress/enhanceApp.js can get access to the router. I think we can allow a theme to do something similar. Idea: if a theme exposes index.js, it can do something similar to this:

// theme/index.js
export default ({ Vue, router, options }) => {
  router.addRoutes([
    {
      path: '/archive',
      component: () => import('./Archive.vue')
    }
  ])
}
lekevicius commented 6 years ago

@yyx990803 That would be great to solve route adding.

Would this also allow route rewriting, that is, transforming 2018-04-16-post-title (.md file) to blog/2018/04/16/post-title (/index.html file)?

Lastly, for making content available, it's related to this line when siteData is being built. What would be an elegant solution to enable content in siteData, for feed?

yeedle commented 6 years ago

running vuepress build rebuilds the entire website which makes sense for a documentation website but not as much for a blog. Is there a straightforward approach to build just the newly added pages?

andreasvirkus commented 6 years ago

Also linking this here (RSS support was already mentioned above) to keep sitemaps in mind. Maybe the other ticket can be closed then? πŸ€·β€β™‚οΈ https://github.com/vuejs/vuepress/issues/52

Other things that my current Metalsmith blog supports and we could implement very easily (sorta nice-to-have features, but at the same time standards nowadays, I suppose):

Maybe also think about nesting themes? So if / uses the default/docs theme, then /blog could use a separate theme and gather everything from blog/*.md as posts? Or should this be solved via themeConfig.docsDir and have two separate builds?

ycmjason commented 6 years ago

A little bit irrelevant but I have written some really hacky code to make the current VuePress looks a little bit more like a blog with the following config.

https://github.com/ycmjason/ycmjason.com/blob/master/.vuepress/config.js

It will automatically generated a side bar with "YYYY MMM" format and then the title of the article would have the date prepended. So I could now easily add a new article without worrying about adding them to side bar.

See the blog live here:

https://www.ycmjason.com

ghost commented 6 years ago

Support for comments using disqus or the like would be welcome as well.

ycmjason commented 6 years ago

@rogersachan planning to do that for my site. And also planning to add tags support.

tdurieux commented 6 years ago

Thanks @mdaffin and @ycmjason, I used your code to create a first version of my blog. It works, ok. I still need to figure out how to handle to tags in the current version

rubick24 commented 6 years ago

Thanks for this discussion, I just migrated my blog from hexo, check Deadalusmask/Arthas.me if it helps. :grin: Arthas.me

And also hope for news about disqus support.

eyleron commented 6 years ago

Documentation versus Blog Features

I've been looking at the VuePress issues and progress and the push to milestone. I totally get drawing a line between "core documentation use case" versus "blog use case". But I think that too can be a form of trap where features that are useful "core features" or "documentation features" get split off into an either/or system.

For my company's software documentation, I'm thinking on using VuePress, and so we could definitely use some of these features that some would consider more "bloggy".

mdaffin commented 6 years ago

@eyleron once the plugin system gets released then things should be more composable. Ideally, it would be nice to keep the core features light and implement most optional features in plugins or separate themes rather than bloating down the core with every possible feature people could want.

Even common things like tags and categories can be harder to make generic across a blog and docs and I think it would be better first designing these features in plugins and themes where there is more freedom to try things out and experiment before setting on a design for things if one can be found. I know I for one have found the tagging system of some static site generators to be limiting for what I wanted to do at times.

luisDanielRoviraContreras commented 6 years ago

An improvement that I think is needed is to be able to add a label in the menu that says example component x (New) or component x (updated) something like this screenshot_30

I would love to help in this

meteorlxy commented 6 years ago

@luisDanielRoviraContreras That's cool, but may not in this blog roadmap

luisDanielRoviraContreras commented 6 years ago

@meteorlxy Yes or we can add it in the .md something like this

---
tag: New
---
andreasvirkus commented 6 years ago

@luisDanielRoviraContreras You already have access to a page's metadata in your theme, so the feature 'exists', it's just a matter of displaying it visually

harryhorton commented 6 years ago

Most of these features mentioned can already be implemented in the non-blog-focused VuePress. What we really need here is a clean list of what kind of extendability is missing.

Creating a separate standard theme repo for a blog setup would be nice, but I think what we need first is a solid plugin system. The moment VuePress steps into the blog space, developers are going to want a wide range of features available. I don't believe that many of these should be the responsibility of core, or even a theme. Instead efforts should be focused on building a plugin system, as that would allow developers to cherry pick the features they want. From there, a theme should be able to require plugins it needs for features such as tag/category systems, archives, 3rd party comment systems, external content management features, etc etc.

eyleron commented 6 years ago

@Johnhhorton So, it sounds like from most of the roadmap and suggestion issues that Core vs Blog feature decisions come down to:

  1. Decide whether belongs in core, now or later.
  2. If not in core, then it must be via plugin (waits on plugin system) or a different use of the core or plugins.
  3. Which theme: core, blog, something.
egoist commented 6 years ago

Hmm I'd rather let VuePress focus on documentation features and have a light-weight blog feature if possible. For example, with following structure:

- docs/
  - blog/
    - hello-world.md
  - guide/
    - getting-started.md

VuePress generates /blog (with post list, pagination etc) and /blog/hello-world.html, no tags no categories, just a blog feature for your documentation.

monicaaikorice commented 6 years ago

Not sure if this matters to others, but maybe allow for theme-building with frameworks such as Quasar?

egoist commented 6 years ago

@monicaaikorice Haven't used Quasar but I think UI frameworks would just work?

monicaaikorice commented 6 years ago

@egoist I'd think so, too, but Quasar has its own CLI and the file structure is a bit different.

whoan commented 6 years ago

Here is a minimalist custom theme I created to migrate my blog to vuepress. Hope it helps someone to solve some problems you will have while implementing custom themes. e.g: managing dependencies specific to the custom theme.

Is is worth mentioning that it is based on the desing of canvas, another blogging system.

xkcoding commented 6 years ago

@ycmjason thanks you , I modified my sidebar based on your config code. This is my config.js and my doc site

xkcoding commented 6 years ago

@whoan awesome theme

ycmjason commented 6 years ago

@xkcoding Can you change your home screen features?

xkcoding commented 6 years ago

@ycmjason so sorry,I will change immediately

ycmjason commented 6 years ago

@xkcoding Don't worry, I just find it weird that my features appear on yours. 😁😁😁

DTrejo commented 6 years ago

(thanks for vuepress I like it a lot)

Handy way to customize your Page with end of post author information, footer, CTA widget without having to eject:

.vuepress/components/Layout.vue

<template>
  <div>
    <Page :sidebar-items="$parent.sidebarItems">
      <!-- <h1 slot="top">{{$page.title}}xx</h1> -->
      <template slot="bottom">
        <Author/>
      </template>
      <!-- {{Object.keys($root.$options.components)}} -->
      <!-- {{Object.keys(Vue.options.components)}} -->
    </Page>
    <div :is="$page.frontmatter.cta || 'CTA'"/>
    <Footer/>
  </div>
</template>

<script>
import Page from 'vuepress/lib/default-theme/Page'
export default {
  components: { Page }
}
</script>

note:slot="top" got left out of the PR that added slot="bottom". But I'm still happy about slot="bottom"!!!

Call to action widget skeleton

.vuepress/components/CTA.vue

<template>
  <div class="cta" v-if="$page.frontmatter.cta !== false">
    <h3>CTA box here</h3>
  </div>
</template>

<style lang="stylus" scoped>
  .cta {
    max-width 31rem
    margin 0 auto
    border 1px solid
    padding 1rem
  }
</style>

Footer with articles

.vuepress/components/Footer.vue

<template>
  <div class="footer">
    <div>
      <h3>Hiring Engineers? You'll like these articles</h3>
      <Articles tag="hiring"/>

      <h3>Growth Engineering Articles</h3>
      <Articles tag="growth"/>

      <h3>How to...</h3>
      <Articles tag="howto"  not="hiring, growth, git, nodejs"/>

      <h3>Node.js</h3>
      <Articles tag="nodejs" not="hiring, growth"/>

      <h3>Git</h3>
      <Articles tag="git"    not="hiring, growth, nodejs"/>

      <!-- <h3>Projects</h3> -->
      <h4><router-link to="/archived.html">Archived</router-link></h4>

      <h3>Find me</h3>
      <a href="https://github.com/DTrejo">Github</a>
      <br/>
      <a href="https://twitter.com/ddtrejo">Twitter</a>
      <br/>
      <a id="email" href="#" title="david at this domain">Email</a>
      <br/>
      <br/>

      <div v-if="$site.themeConfig.footer">
        {{ $site.themeConfig.footer }}
      </div>
    </div>
  </div>
</template>

<style lang="stylus" scoped>
  @import '../override.styl'
  .footer {
    margin-top 5rem
    padding 3rem 0
    background-color $textColor
    color $borderColor
  }
  .footer > * {
    max-width 33rem
    margin 0 auto
  }
</style>

Article list component that lets you filter by tag (based on the one posted above, ty!)

.vuepress/components/Articles.vue

<template>
  <ol>
    <li
      v-for="post in $site.pages.sort((a, b) =>
        -1 * (a.frontmatter.date || '').localeCompare(b.frontmatter.date)
      )"
      v-if="(!tag || tags(post).includes(tag))
        && !intersects(tags(post), parseTags(not))"
      :key="post.frontmatter.title"
    >
      <router-link :to="post.path">
        <div class="title">{{ post.title }}</div>
        <!-- <div class="date">{{ new Date(post.frontmatter.date).toLocaleDateString() }}</div> -->
        <!-- <div class="description">{{ post.frontmatter.description }}</div> -->
        <!-- TODO: include excerpt instead? -->
      </router-link>
      <!-- style="white-space: pre; font-family: monaco, monospace;"
      {{JSON.stringify([this,tag, post], null, 2)}} -->
      <!-- it is okay to put this in an <article> if you include excerpt etc -->
    </li>
  </ol>
</template>

<script>
export default {
  props: {
    tag: {
      type: String
    },
    not: {
      type: String,
      default: ''
    }
  },
  methods: {
    parseTags,
    tags(post) {
      return parseTags(post.frontmatter.tags)
    },
    intersects(a, b) {
      // console.log('intersects', a, '|', b, '===', a.some(el => b.includes(el)))
      return a.some(el => b.includes(el))
    }
  }
}

function parseTags (raw) {
  // handle "abc" and "abc, def"
  if (typeof raw === 'string') {
    return raw.split(',').map(s => s.trim())
  }
  return raw || []
}
</script>

Thanks everyone!

PS I'm not "done" yet so I haven't published anything, but here's what one of my articles looks like:

localhost_8080_2018-01-11-referrals html

david-trejo-ck commented 6 years ago

@yeedle said

What about comments? A default theme should perhaps offer a commenting component that integrates one of the popular commenting platforms.


What if we pulled in github comments for the corresponding markdown document? I remember I saw there was a project that did this, I don't know how involved it was to set up though.

xkcoding commented 6 years ago

@david-trejo-ck Is this repo Gitalk / demo page or this repo Gitment / demo page?

FossPrime commented 6 years ago

@ycmjason did you make any progress on adding Disqus to your vue-press site? what issues did you run into?

ycmjason commented 6 years ago

@rayfoss i haven't done it. The disqus add-on probably need a custom theme. Since the default theme is still changing quite frequently, I want to wait before ejecting.

ycmjason commented 6 years ago

But it could also be done with plugin, so i will just wait a bit.

arkceajin commented 6 years ago

I think the features like blog tag/category are the most people needed, should make them be the part of the default theme, or more theme demos show how to achieve the popular requested features. Guide how to write&add features in my theme(in the HP but not GitHub issue) shall be better than just put them into Vuepress...

ycmjason commented 6 years ago

@arkceajin so the direction that vuepress wants to go is technical documents. Not for blogs.

So it would be more suitable for blogs to live in a separate theme.

octref commented 6 years ago

I modded Vuepress + made a theme for my blog. Here is the (meta) blog post: http://blog.matsu.io/back-to-blogging-with-vuepress, in case anyone is interested.

awulkan commented 6 years ago

@octref I see that you have pretty URLs on your blog, that's exactly what I recently started working on here: #608 .

I don't really know how your code works, but the way I generated my URLs still allowed for normal content file structure, like shown here: https://github.com/vuejs/vuepress/issues/78#issuecomment-395945362

Does your code allow for a normal content structure? If so, that's awesome.

octref commented 6 years ago

@AWulkan It does, you can see https://github.com/octref/blog (or even build it with yarn && yarn build ). Lack of Clean URL just drives me crazy.

awulkan commented 6 years ago

@octref But it looks like you have each file named index.md, and then you have to put them in a folder with the name of the path. What I meant was the ability to turn /blog/my-post.md into /blog/my-post/index.html automatically.

Also, does it remove the .html extension?