Blog
This Meteor package gives you a basic, out-of-the-box blog at /blog
. We wanted
a way to add a blog to an existing app without running another dyno or server
for a meteor-based blog.
This blog is very much a work in progress. To help decide what gets add next, vote with your Github issues!
Features
- Medium-style editor
- Slug-based URLs (editable)
- Add images (store in database or upload to S3)
- Support DISQUS comments
- Blog post tags and tag view
- Widget to embed recent posts on another (e.g. home) page
- Customizable templates
- SEO best practices (OpenGraph, Twitter Cards, share buttons, Google+ author attribution)
- Autosave
- Pagination
- Code syntax highlighting
- Multiple roles (admin/author)
- RSS feed
Roadmap
- Check out the enhancements tracker
Quick Start
$ meteor add ryw:blog
You will get routes for:
/blog /admin/blog
/admin/blog
requires that Meteor.user()
return a user.
Usage
Roles
By default, any logged-in user can administer the blog. To ensure that only select users can edit the blog, the package supports two roles:
adminRole
- Can create, and modify or delete any post.authorRole
- Can create, and modify or delete only my own posts.
To enable either or both roles, specify values in the blog config:
# CoffeeScript if Meteor.isServer Blog.config adminRole: 'blogAdmin' authorRole: 'blogAuthor'
1// JavaScript 2if (Meteor.isServer) { 3 Blog.config({ 4 adminRole: 'blogAdmin', 5 authorRole: 'blogAuthor' 6 }); 7}
Then, you need to give blog users that role. Currently, you're on your own to add these roles somehow:
- Add these directly to admin users in the database (
"roles": ["blogAdmin"]
), or - Roll your own admin page using the methods provided by meteor-roles, or
- Use an accounts admin package like accounts-admin-ui-bootstrap-3.
Comments
DISQUS
This package supports DISQUS comments. Configure your
DISQUS short name in the client and comments will render below all your blog
posts. If you use your own blogShowTemplate
template, include {{> disqus this}}
to
display comments.
# CoffeeScript if Meteor.isClient Blog.config comments: disqusShortname: 'myshortname'
1// JavaScript 2if (Meteor.isClient) { 3 Blog.config({ 4 comments: { 5 disqusShortname: 'myshortname' 6 } 7 }); 8}
SideComments.js
This package has experimental integration with SideComments.js. Enable side comments in your blog settings. Currently, side comments uses the Meteor accounts for your Meteor site as comment users, which is probably not what you want. You can also allow anonymous comments, which lets anyone type in anything without even a name. Also, probably not what you want.
# CoffeeScript if Meteor.isClient Blog.config comments: useSideComments: true # default is false allowAnonymous: true # default is false
1// JavaScript 2if (Meteor.isClient) { 3 Blog.config({ 4 comments: { 5 useSideComments: true, 6 allowAnonymous: true 7 } 8 }); 9}
Bootstrap Templates
Meteor blog works out-of-the-box with minimal, decent-looking Bootstrap
templates. If you use these default templates, you must add the meteor
bootstrap-3
package.
$ meteor add mrt:bootstrap-3
Custom Templates
While the admin templates are opinionated, the front-end is bare markup, ready to by styled. If the default templates aren't doing it for you, you can override the default templates with your own by setting configuration variables:
# CoffeeScript if Meteor.isClient Blog.config blogIndexTemplate: 'myBlogIndexTemplate' # '/blog' route blogShowTemplate: 'myShowBlogTemplate' # '/blog/:slug' route
1// JavaScript 2if (Meteor.isClient) { 3 Blog.config({ 4 blogIndexTemplate: 'myBlogIndexTemplate', 5 blogShowTemplate: 'myShowBlogTemplate' 6 }); 7}
In your templates, you can use these Handlebars helpers provided by the package to display blog posts with some basic, semantic markup:
{{> blogIndex}}
- Renders list of blog posts (/blog
route){{> blogShow}}
- Renders single blog post (/blog/:slug
route)
Example:
1<template name="myBlogIndexTemplate"> 2 <h1>Welcome to my Blog</h1> 3 <div>{{> blogIndex}}</div> 4</template>
If you don't want any of our markup, use the blog data provided in the template context directly:
posts
- Collection ofminimongoid
blog post objects (/blog
route)this
-minimongoid
blog post object (/blog/:slug
route)
Example:
1<template name="myBlogIndexTemplate"> 2 <h1>Welcome to my Blog</h1> 3 <ul> 4 {{#each posts}} 5 <li> 6 <h2>{{title}}</h2> 7 <p>Published on {{publishedAt}}</p> 8 <p>Excerpt: {{excerpt}}</p> 9 </li> 10 {{/each}} 11 </ul> 12</template>
Custom NotFound
You can provide a custom notFoundTemplate
to use when a blog post slug is not
found.
# CoffeeScript if Meteor.isClient Blog.config blogNotFoundTemplate: 'myNotFoundTemplate'
1// JavaScript 2if (Meteor.isClient) { 3 Blog.config({ 4 blogNotFoundTemplate: 'myNotFoundTemplate' 5 }); 6}
Blog Post Excerpt
By default, blog summaries or excerpts are generated by taking the 1st paragraph
from the blog post. You can override this function by configuring a custom
excerptFunction
. For example, if you wanted to create an excerpt from the 1st
sentence:
# CoffeeScript if Meteor.isClient Blog.config excerptFunction: (body) -> body.split('.')[0] + '.'
1// JavaScript 2if (Meteor.isClient) { 3 Blog.config({ 4 excerptFunction: function(body) { 5 return body.split('.')[0] + '.'; 6 } 7 }); 8}
Images
Adding images to your blog posts works out of the box and saves the images to gridFS in your Mongo database. You can optionally have these images to an Amazon S3 bucket that you configure.
To setup S3 for file storage, add the following in /settings.json
(or any
other location of your choice).
1{ 2 "public": { 3 "blog": { 4 "useS3": true 5 } 6 }, 7 "private": { 8 "blog": { 9 "s3Config": { 10 "bucket": "you-bucket-name", 11 "ACL": "public-read", 12 "MaxTries": 2, 13 "accessKeyId": "XXXXXXXXXXXXX", 14 "secretAccessKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 15 "region": "OPTIONAL most of the time" 16 } 17 } 18 } 19}
Pagination
By default, blog posts are paged in 20 at a time. You can modify this value in
settings. Set to null
to turn off paging entirely.
# CoffeeScript if Meteor.isClient Blog.config pageSize: 10
1// JavaScript 2if (Meteor.isClient) { 3 Blog.config({ 4 pageSize: 10 5 }); 6}
The default blogIndexTemplate
template displays a Load More
button. If you
use your own template, include the {{blogPager}}
helper to display the button.
Code Highlighting
If you fancy a coding blog, the blog package supports syntax highlighting using
highlight.js. If enabled, any content within <pre>
tags will get modified for syntax highlighting. You can specify any
highlight.js
style file.
Example config:
# CoffeeScript if Meteor.isClient Blog.config syntaxHighlighting: true # default is false syntaxHighlightingTheme: 'atelier-dune.dark' # default is 'github'
1// JavaScript 2if (Meteor.isClient) { 3 Blog.config({ 4 syntaxHighlighting: true, 5 syntaxHighlightingTheme: 'atelier-dune.dark' 6 }); 7}
Social Sharing
This package depends on the shareit
package
for powering social sharing. If you use your own blogShowTemplate
template,
include {{> shareit}}
to display share buttons.
Recent Posts Helper
You can include a basic snippet of HTML displaying recent blog posts (e.g. on your home page). Insert the inclusion helper where you want the recent posts to appear.
1{{> blogLatest}}
Or you can specify the # of posts to show:
1{{> blogLatest num=5}}
There are classes in the template for styling.
RSS
An RSS feed is automatically generated at /rss/posts
. To set the title and
description in the feed, configure RSS:
# CoffeeScript if Meteor.isServer Blog.config rss: title: 'My blog title' description: 'My blog description'
1// JavaScript 2if (Meteor.isServer) { 3 Blog.config({ 4 rss: { 5 title: 'My blog title', 6 description: 'My blog description' 7 } 8 }); 9}
Add a head tag somewhere in your .html
files so your RSS feed can be discovered:
1<head> 2 <link rel="alternate" type="application/rss+xml" title="My blog title" href="/rss/posts"> 3</head>