Skip to content

Commit

Permalink
feat: add reading time information to posts
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonroberts committed Jul 14, 2020
1 parent 00ea814 commit d2f75d3
Show file tree
Hide file tree
Showing 17 changed files with 141 additions and 36 deletions.
3 changes: 2 additions & 1 deletion content/posts/2019-03-04-handling-error-states-with-ngrx.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ published: true
slug: 2019-03-04-handling-error-states-with-ngrx
publishedDate: 2019-03-04
---
<div id="post-info"></div>

## Handling Error States with NgRx
<br/>

<a href="https://unsplash.com/@soymeraki?utm_medium=referral&amp;utm_campaign=photographer-credit&amp;utm_content=creditBadge" target="_blank" title="Photo by David Travis on Unsplash">
<img src="/assets/posts/david-travis-548920-unsplash.jpg" width="100%"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ published: true
slug: 2019-03-27-custom-route-matching-angular-router
publishedDate: 2019-03-27
---
<div id="post-info"></div>

## Custom Route Matching with the Angular Router
<br/>

<a href="https://unsplash.com/@soymeraki?utm_medium=referral&amp;utm_campaign=photographer-credit&amp;utm_content=creditBadge" target="_blank" title="Photo by Javier Allegue Barros on Unsplash">
<img src="/assets/posts/javier-allegue-barros-761133-unsplash.jpg" width="100%"/>
Expand Down
3 changes: 2 additions & 1 deletion content/posts/2020-05-14-angular-unfiltered-001.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ published: true
slug: 2020-05-14-angular-unfiltered-001
publishedDate: '2020-05-14 02:00 PM CST'
---
<div id="post-info"></div>

## Angular Unfiltered Episode 001: Angular Forms Quick Chat
<br/>

In the first episode of Angular Unfiltered, I had a rather impromptu chat with my friend [Mike Ryan](https://twitter.com/MikeRyanDev). The discussion was prompted by a tweet asking which Angular Forms library is best:

Expand Down
3 changes: 2 additions & 1 deletion content/posts/2020-05-14-mixing-action-styles-ngrx.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ published: true
slug: 2020-05-14-mixing-action-styles-ngrx
publishedDate: '2020-05-14 02:00 PM CST'
---
<div id="post-info"></div>

## Mixing Action Styles In NgRx State
<br/>

<a href="https://unsplash.com/@franckinjapan?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" target="_blank" title="Photo by Franck V. on Unsplash">
<img src="/assets/posts/franck-v-miWGZ02CLKI-unsplash.jpg" width="100%"/>
Expand Down
3 changes: 2 additions & 1 deletion content/posts/2020-05-15-angular-unfiltered-002.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ published: true
slug: 2020-05-15-angular-unfiltered-002
publishedDate: '2020-05-15 02:00 PM CST'
---
<div id="post-info"></div>

## Angular Unfiltered Episode 002: Angular Forms Quick Chat
<br/>

In another episode of Angular Unfiltered, me and [Zack DeRose](https://twitter.com/zackderose), a Senior Angular Engineer at Nrwl continued the conversation about forms in Angular.

Expand Down
3 changes: 2 additions & 1 deletion content/posts/2020-05-22-angular-unfiltered-003.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ published: true
slug: 2020-05-22-angular-unfiltered-003
publishedDate: '2020-05-22 02:00 PM CST'
---
<div id="post-info"></div>

## Angular Unfiltered Episode 003: Quick Chat
<br/>

In another episode of Angular Unfiltered, me and [Austin Akers](https://twitter.com/tweetmonster999), a Senior Software Engineer at Allstate talked about contributing to open source, mentorship, breakdancing, and more!

Expand Down
3 changes: 2 additions & 1 deletion content/posts/2020-06-12-angular-unfiltered-004.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ published: true
slug: 2020-05-22-angular-unfiltered-004
publishedDate: '2020-06-12 02:00 PM CST'
---
<div id="post-info"></div>

## Angular Unfiltered Episode 004: Quick Chat
<br/>

In another episode of Angular Unfiltered, me and [Devin Shoemaker](https://twitter.com/paranoidcoder) talked about contributing to open source, using React with Nx, Nx plugin development, and more!.

Expand Down
3 changes: 2 additions & 1 deletion content/posts/2020-06-19-angular-unfiltered-005.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ published: true
slug: 2020-06-19-angular-unfiltered-005
publishedDate: '2020-06-19 02:00 PM CST'
---
<div id="post-info"></div>

## Angular Unfiltered Episode 005: Quick Chat
<br/>

In another episode of Angular Unfiltered, me and [Luke Howell](https://twitter.com/LukeHowellDev), a personal friend, and UI Architect talked about marketing for the Army, challenges with Angular styling packages, interacting with designers, and more!.

Expand Down
3 changes: 2 additions & 1 deletion content/posts/2020-06-26-angular-unfiltered-006.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ published: true
slug: 2020-06-26-angular-unfiltered-006
publishedDate: '2020-06-26 02:00 PM CST'
---
<div id="post-info"></div>

## Angular Unfiltered Episode 006: Quick Chat
<br/>

In another episode of Angular Unfiltered, me and [Bryan Wilhite](https://twitter.com/BryanWilhite) talked about Physics, coming up in a Microsoft ecosystem, building a blog in Angular without losing your SEO, and more!

Expand Down
6 changes: 4 additions & 2 deletions content/posts/2020-07-06-lazy-loading-routes-observable.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
---
title: 'Lazy Loading Routes using Observables with the Angular Router'
title: 'Lazy Loading Routes using an Observable with the Angular Router'
description: 'Describes how to use an Observable when lazy loading routes with the Angular Router'
published: true
slug: 2020-07-06-lazy-loading-routes-observable
publishedDate: '2020-07-06 02:00 PM CST'
---
## Lazy Loading Routes using an Observable with the Angular Router
<div id="post-info"></div>

<br/>

<a href="https://unsplash.com/@kevin_butz?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText" title="Photo by Kevin Butz on Unsplash">
<img src="/assets/posts/kevin-butz-4xZTX1CZBVE-unsplash.jpg" width="100%"/>
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@
"@angular/platform-browser": "~9.1.4",
"@angular/platform-browser-dynamic": "~9.1.4",
"@angular/router": "~9.1.4",
"@scullyio/init": "^0.0.28",
"@scullyio/ng-lib": "latest",
"@scullyio/scully": "latest",
"@scullyio/init": "0.0.29",
"@scullyio/ng-lib": "0.0.27",
"@scullyio/scully": "0.0.101",
"core-js": "^2.5.4",
"ngx-markdown": "^8.1.0",
"path-to-regexp": "^6.1.0",
"prism-themes": "^1.0.1",
"prismjs": "^1.20.0",
"reading-time": "^1.2.0",
"rxjs": "~6.5.3",
"tslib": "^1.10.0",
"zone.js": "~0.10.2"
Expand Down
26 changes: 26 additions & 0 deletions scully-plugins/post-info.plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/** import from scully the register plugin function */
const {registerPlugin} = require('@scullyio/scully');
const fs = require('fs');
const readingTime = require('reading-time');

/** import from scully the register plugin function */
const postInfo = async (routes) => {
routes.forEach(route => {
if (route.route.startsWith('/blog/posts')) {
const content = fs.readFileSync(route.templateFile).toString('utf-8');
const stats = readingTime(content);

route.data.readingTime = stats.minutes > 1 ? parseInt(stats.minutes, 10) : 1
}
});

return Promise.resolve(routes);
};
/**
You can add extra validator for your custom plugin
*/
const validator = async conf => [];
/**
registerPlugin(TypeOfPlugin, name of the plugin, plugin function, validator)
*/
registerPlugin('routeProcess', 'postInfo', postInfo, validator);
1 change: 1 addition & 0 deletions scully.blog.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require('./scully-plugins/post-info.plugin.js');
import { ScullyConfig } from '@scullyio/scully';

export const config: ScullyConfig = {
Expand Down
7 changes: 3 additions & 4 deletions src/app/blog/blog.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { CommonModule } from '@angular/common';
import { MatListModule } from '@angular/material/list';
import { RouterModule } from '@angular/router';

import { ScullyRoutesService, ScullyRoute } from '@scullyio/ng-lib';
import { Observable } from 'rxjs';
import { ScullyRoutesService } from '@scullyio/ng-lib';
import { map } from 'rxjs/operators';

@Component({
Expand All @@ -18,7 +17,7 @@ import { map } from 'rxjs/operators';
<a routerLink="{{ post.route }}">{{ post.title }}</a>
</h2>
<p mat-line>{{ post.publishedDate | date }}</p>
<p mat-line>{{ post.publishedDate | date:'longDate' }} - {{ post.readingTime }} min read</p>
</mat-list-item>
</mat-list>
`,
Expand All @@ -43,7 +42,7 @@ import { map } from 'rxjs/operators';
})
export class BlogComponent {
posts$ = this.routesService.available$.pipe(
map((routes) => routes.filter((route) => route.route.startsWith('/blog'))),
map((routes) => routes.filter((route) => route.route.startsWith('/blog/posts'))),
map((filteredRoutes) =>
filteredRoutes
.slice()
Expand Down
20 changes: 17 additions & 3 deletions src/app/blog/post.component.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { CommonModule } from '@angular/common';
import {
Component,
AfterViewChecked,
ViewEncapsulation,
NgModule,
} from '@angular/core';
import { ScullyLibModule } from '@scullyio/ng-lib';
import { ScullyLibModule, ScullyRoutesService } from '@scullyio/ng-lib';

import { HighlightService } from '../highlight.service';
import { PostCommentsComponentModule } from './comments.component';
import { map } from 'rxjs/operators';

@Component({
selector: 'app-post',
template: `
<h2>{{ title$ | async }}</h2>
<span>{{ publishedDate$ | async | date:'longDate' }} - {{ readingTime$ | async }} min read</span>
<!-- This is where Scully will inject the static HTML -->
<scully-content></scully-content>
Expand All @@ -22,7 +28,15 @@ import { PostCommentsComponentModule } from './comments.component';
encapsulation: ViewEncapsulation.Emulated,
})
export class PostComponent implements AfterViewChecked {
constructor(private highlightService: HighlightService) {}
current$ = this.routes.getCurrent();
title$ = this.current$.pipe(map(route => route.title));
publishedDate$ = this.current$.pipe(map(route => route.publishedDate));
readingTime$ = this.current$.pipe(map(route => route.readingTime));

constructor(
private highlightService: HighlightService,
private routes: ScullyRoutesService
) {}

ngAfterViewChecked() {
this.highlightService.highlightAll();
Expand All @@ -31,6 +45,6 @@ export class PostComponent implements AfterViewChecked {

@NgModule({
declarations: [PostComponent],
imports: [ScullyLibModule, PostCommentsComponentModule],
imports: [CommonModule, ScullyLibModule, PostCommentsComponentModule],
})
export class PostComponentModule {}
2 changes: 1 addition & 1 deletion src/assets/scully-routes.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"route":"/about","title":"About Me","description":"About Me","published":true,"slug":"about","sourceFile":"about.md"},{"route":"/talks","title":"Tech Talks and Appearances","description":"Stuff","published":true,"slug":"talks","sourceFile":"talks.md"},{"route":"/blog/posts/2019-03-04-handling-error-states-with-ngrx","title":"Handling Error States with NgRx","description":"Handling Error States with NgRx","published":true,"slug":"2019-03-04-handling-error-states-with-ngrx","publishedDate":"2019-03-04T00:00:00.000Z","sourceFile":"2019-03-04-handling-error-states-with-ngrx.md"},{"route":"/blog/posts/2019-03-27-custom-route-matching-angular-router","title":"Custom Route Matching with the Angular Router","description":"Custom Route Matching with the Angular Router","published":true,"slug":"2019-03-27-custom-route-matching-angular-router","publishedDate":"2019-03-27T00:00:00.000Z","sourceFile":"2019-03-27-custom-route-matching-angular-router.md"},{"route":"/blog/posts/2020-05-14-angular-unfiltered-001","title":"Angular Unfiltered Episode 001: Angular Forms w/Mike Ryan","description":"Chatting with Mike Ryan about Forms in Angular","published":true,"slug":"2020-05-14-angular-unfiltered-001","publishedDate":"2020-05-14 02:00 PM CST","sourceFile":"2020-05-14-angular-unfiltered-001.md"},{"route":"/blog/posts/2020-05-14-mixing-action-styles-ngrx","title":"Mixing Action Styles in NgRx State","description":"Mixing Action Styles in NgRx State","published":true,"slug":"2020-05-14-mixing-action-styles-ngrx","publishedDate":"2020-05-14 02:00 PM CST","sourceFile":"2020-05-14-mixing-action-styles-ngrx.md"},{"route":"/blog/posts/2020-05-15-angular-unfiltered-002","title":"Angular Unfiltered Episode 002: Angular Forms Pt. 2 w/Zack DeRose","description":"Chatting with Zack DeRose about Forms in Angular","published":true,"slug":"2020-05-15-angular-unfiltered-002","publishedDate":"2020-05-15 02:00 PM CST","sourceFile":"2020-05-15-angular-unfiltered-002.md"},{"route":"/blog/posts/2020-05-22-angular-unfiltered-003","title":"Angular Unfiltered Episode 003: Quick Chat w/Austin Akers","description":"Chatting with Austin Akers","published":true,"slug":"2020-05-22-angular-unfiltered-003","publishedDate":"2020-05-22 02:00 PM CST","sourceFile":"2020-05-22-angular-unfiltered-003.md"},{"route":"/blog/posts/2020-05-22-angular-unfiltered-004","title":"Angular Unfiltered Episode 004: Quick Chat w/Devin Shoemaker","description":"Chatting with Devin Shoemaker","published":true,"slug":"2020-05-22-angular-unfiltered-004","publishedDate":"2020-06-12 02:00 PM CST","sourceFile":"2020-06-12-angular-unfiltered-004.md"},{"route":"/blog/posts/2020-06-19-angular-unfiltered-005","title":"Angular Unfiltered Episode 005: Quick Chat w/Luke Howell","description":"Chatting with Luke Howell","published":true,"slug":"2020-06-19-angular-unfiltered-005","publishedDate":"2020-06-19 02:00 PM CST","sourceFile":"2020-06-19-angular-unfiltered-005.md"},{"route":"/blog/posts/2020-06-26-angular-unfiltered-006","title":"Angular Unfiltered Episode 006: Quick Chat w/Bryan Wilhite","description":"Chatting with Bryan Wilhite","published":true,"slug":"2020-06-26-angular-unfiltered-006","publishedDate":"2020-06-26 02:00 PM CST","sourceFile":"2020-06-26-angular-unfiltered-006.md"},{"route":"/blog/posts/2020-07-06-lazy-loading-routes-observable","title":"Lazy Loading Routes using Observables with the Angular Router","description":"Describes how to use an Observable when lazy loading routes with the Angular Router","published":true,"slug":"2020-07-06-lazy-loading-routes-observable","publishedDate":"2020-07-06 02:00 PM CST","sourceFile":"2020-07-06-lazy-loading-routes-observable.md"},{"route":"/blog"},{"route":"/"}]
[{"route":"/about","title":"About Me","description":"About Me","published":true,"slug":"about","sourceFile":"about.md"},{"route":"/talks","title":"Tech Talks and Appearances","description":"Stuff","published":true,"slug":"talks","sourceFile":"talks.md"},{"route":"/blog/posts/2019-03-04-handling-error-states-with-ngrx","title":"Handling Error States with NgRx","description":"Handling Error States with NgRx","published":true,"slug":"2019-03-04-handling-error-states-with-ngrx","publishedDate":"2019-03-04T00:00:00.000Z","sourceFile":"2019-03-04-handling-error-states-with-ngrx.md","readingTime":5},{"route":"/blog/posts/2019-03-27-custom-route-matching-angular-router","title":"Custom Route Matching with the Angular Router","description":"Custom Route Matching with the Angular Router","published":true,"slug":"2019-03-27-custom-route-matching-angular-router","publishedDate":"2019-03-27T00:00:00.000Z","sourceFile":"2019-03-27-custom-route-matching-angular-router.md","readingTime":3},{"route":"/blog/posts/2020-05-14-angular-unfiltered-001","title":"Angular Unfiltered Episode 001: Angular Forms w/Mike Ryan","description":"Chatting with Mike Ryan about Forms in Angular","published":true,"slug":"2020-05-14-angular-unfiltered-001","publishedDate":"2020-05-14 02:00 PM CST","sourceFile":"2020-05-14-angular-unfiltered-001.md","readingTime":1},{"route":"/blog/posts/2020-05-14-mixing-action-styles-ngrx","title":"Mixing Action Styles in NgRx State","description":"Mixing Action Styles in NgRx State","published":true,"slug":"2020-05-14-mixing-action-styles-ngrx","publishedDate":"2020-05-14 02:00 PM CST","sourceFile":"2020-05-14-mixing-action-styles-ngrx.md","readingTime":3},{"route":"/blog/posts/2020-05-15-angular-unfiltered-002","title":"Angular Unfiltered Episode 002: Angular Forms Pt. 2 w/Zack DeRose","description":"Chatting with Zack DeRose about Forms in Angular","published":true,"slug":"2020-05-15-angular-unfiltered-002","publishedDate":"2020-05-15 02:00 PM CST","sourceFile":"2020-05-15-angular-unfiltered-002.md","readingTime":1},{"route":"/blog/posts/2020-05-22-angular-unfiltered-003","title":"Angular Unfiltered Episode 003: Quick Chat w/Austin Akers","description":"Chatting with Austin Akers","published":true,"slug":"2020-05-22-angular-unfiltered-003","publishedDate":"2020-05-22 02:00 PM CST","sourceFile":"2020-05-22-angular-unfiltered-003.md","readingTime":1},{"route":"/blog/posts/2020-05-22-angular-unfiltered-004","title":"Angular Unfiltered Episode 004: Quick Chat w/Devin Shoemaker","description":"Chatting with Devin Shoemaker","published":true,"slug":"2020-05-22-angular-unfiltered-004","publishedDate":"2020-06-12 02:00 PM CST","sourceFile":"2020-06-12-angular-unfiltered-004.md","readingTime":1},{"route":"/blog/posts/2020-06-19-angular-unfiltered-005","title":"Angular Unfiltered Episode 005: Quick Chat w/Luke Howell","description":"Chatting with Luke Howell","published":true,"slug":"2020-06-19-angular-unfiltered-005","publishedDate":"2020-06-19 02:00 PM CST","sourceFile":"2020-06-19-angular-unfiltered-005.md","readingTime":1},{"route":"/blog/posts/2020-06-26-angular-unfiltered-006","title":"Angular Unfiltered Episode 006: Quick Chat w/Bryan Wilhite","description":"Chatting with Bryan Wilhite","published":true,"slug":"2020-06-26-angular-unfiltered-006","publishedDate":"2020-06-26 02:00 PM CST","sourceFile":"2020-06-26-angular-unfiltered-006.md","readingTime":1},{"route":"/blog/posts/2020-07-06-lazy-loading-routes-observable","title":"Lazy Loading Routes using an Observable with the Angular Router","description":"Describes how to use an Observable when lazy loading routes with the Angular Router","published":true,"slug":"2020-07-06-lazy-loading-routes-observable","publishedDate":"2020-07-06 02:00 PM CST","sourceFile":"2020-07-06-lazy-loading-routes-observable.md","readingTime":4},{"route":"/blog"},{"route":"/"}]

0 comments on commit d2f75d3

Please sign in to comment.