Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

🐙 Turn your github issues into a CMS for your blog.

License

NotificationsYou must be signed in to change notification settings

renatorib/github-blog

Repository files navigation

Turn your github issues into a CMS for your blog.

npm install @rena.to/github-blog

API Only

This repository is just about the API.

Note:

If you're looking for something more 'high level', like a full-featured blog application, I'm working on a starter template using Next.js, TypeScript and Tailwindcss.Follow me on twitter to follow up and receive updates.

Concept

The main idea is simple: each issue is a blog post entity.

Taxonomy is managed bylabels and have<key>:<value> structure. Liketype:post,tag:javascript, etc. Labels can be used to filter posts on querying, but is also available on post too. So you can use to add any kind of flags to your post.

The built-in label keys are:type,state,tag,flag andslug.

  • Usetype labels to differentiatepost fromarticle, for example.
  • Usestate labels to handlepublished anddraft.
  • Usetag labels to add tags to your posts, liketypescript.
  • Useflag labels to add any kind of flag to your post, likeoutdated to mark post as outdated.
  • Useslug label to define an slug to your post.Read about slug problem.

You can also add anyk:v labels to your post, likefoo:bar.

Table of Contents

Getting Started

Let's create your first blog post.
You will need: 1) a repository, 2) an issue with some labels

Repository

First, you will need to create a repository to publish your posts.

It can be private, but I recommend you to create a public since it will allow people comment and react to your posts.
Random people will be able to create issues but they can't add labels. So you can control what posts will be shown using some label liketype:post for example. It will prevent random people to post on your blog. Also, by core github-blog only fetches by opened issues. You can close any random issue opened by others to keep posts organized.

image

Issue

Create a issue with your content and add the labelsstate:published,type:post.
Also add an label to your slug likeslug:my-first-post.

Tip: Your issue content can have frontmatter data

image

Fetch

Here comes github-blog. First install

npm install @rena.to/github-blog

Now create a new blog instance passing your repo and your github token.
Create your token here ⟶.

import{valueGithubBlog}from"@rena.to/github-blog";constblog=newGithubBlog({repo:"<user>/<repo>",// e.g.: "renatorib/posts"token:"<token>",});

Fetch your post using getPost:

constpost=awaitblog.getPost({query:{slug:"my-first-post"},});

Fetch post comments using getComments:

constcomments=awaitblog.getComments({query:{slug:"my-first-post"},pager:{first:100},});

Fetch all your posts using getPosts:

constposts=awaitblog.getPosts({query:{type:"post",state:"published"},pager:{limit:10,offset:0},});

That's all.

Guides

Querying

All query works by AND logic. You can't query by OR because of the nature and limitations of github search.
But you can exclude results using prefixnot (notType,notState, etc.)
E.g: If you want to query posts with typepost but it can't have a flagoutdated, you can use:

constposts=awaitblog.getPosts({query:{type:"post",notFlag:"outdated"},pager:{limit:10,offset:0},});

You can also pass an array to most of query params:

constposts=awaitblog.getPosts({query:{type:["post","article"],tag:["javascript","react"]},pager:{limit:10,offset:0},});

Searching

You can also search for post that contain terms usingquery.search param:

constposts=awaitblog.getPosts({query:{type:"post",state:"published",search:"compiler"},pager:{limit:10,offset:0},});

Sorting

You can sort results byinteractions,reactions,author-date,created,updated.
All of them are desc by default but you can suffix with-asc. See allin docs

constposts=awaitblog.getPosts({query:{type:"post",sort:"interactions"},pager:{limit:10,offset:0},});

Pagination

You can paginate usingpager.limit andpager.offset as you saw before, but you can also paginate using cursors with the pager paramsafter,before,first andlast.

// first 10 postsconstposts=awaitblog.getPosts({query:{type:"post"},pager:{first:10},});// more 10 postsconstmorePosts=awaitblog.getPosts({query:{type:"post"},pager:{first:10,after:posts.pageInfo.endCursor},});

NOTE:limit andoffset usesfirst andafter under the hood.
So if you pass bothlimit andfirst oroffset andafter, limit and offset will be ignored.

Defaults

You can set some defaults for querying right in your blog instance, if you want to avoid some query repetition:

constblog=newGithubBlog({repo:"renatorib/posts",token:process.env.GITHUB_TOKEN,queryDefaults:{state:"published",type:"post",},});constposts=awaitblog.getPosts({pager:{first:10,offset:0},});

Comments

You can fetch all post comments usinggetComments method

// first 10 commentsconstcomments=awaitblog.getComments({query:{slug:"my-first-post"},pager:{first:10},});// more 10 postsconstmoreComments=awaitblog.getComments({query:{slug:"my-first-post"},pager:{first:10,after:comments.pageInfo.endCursor},});

NOTE: Comment pagination bylimit andoffset is still not possible while I figure out on how generate v2 cursors based on offset.
Read more about this issue here, maybe you can help.

Problems

Github issues and Github API of course isn't designed to this kind of usage. So I ended up bumping into some limitations during the design and construction of the project. Here I list some of them and try to describe the problem and how I tried to get around.

Slug Problem

One of my biggest disappointments. It's impossible to create a safe and unique slug for your posts.

My first attempt was to use issue title to slug, and define the actual post title into issue's frontmatter.
But it does not worked because:

Github only let you query for an exact repo/issue using the number of it, and I don't want to put id/number into my urls.

query {repository(owner:"renatorib",name:"posts") {issue(number:1) { //getissueathttps://github.com/renatorib/posts/issue/1title    }  }}

Github repository issues only allow you to filter using labels, states (closed/open), assignee, dates, etc. Nothing that let me use the title.

query {repository(owner:"renatorib",name:"posts") {issues(...filters) {  //somespecificfilters,nothingusefultitle    }  }}

So I was forced to use thequery search that I find more powerful and I could filter byrepo:owner/nameNow I can find the issue using title this way:

query {search(type: ISSUE,first:1,query:"repo:renatorib/posts slug-name") {nodes {...onIssue {title      }    }  }}

But it isn'treliable. I can't search for anexact title with query search and it could return an issue with title ofslug-name-foo instead of theslug-name depending on the sort rules.

I gave up and ended using labels for that. Now I can query by exact slug:

query {search(type: ISSUE,first:1,query:"repo:renatorib/posts label:slug:slug-name") {nodes {...onIssue {title      }    }  }}

It works. But the problem is that it isn't the ideal. Each post is a new label, it don't scale well.

Pagination by limit/offset problem

TODO

API Reference

See at/docs (auto-generated from typescript types)

About

🐙 Turn your github issues into a CMS for your blog.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors2

  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp