1
0
mirror of https://github.com/trambarhq/relaks-wordpress-example.git synced 2025-09-24 22:41:31 +02:00

Changed to slug-based routing.

This commit is contained in:
Chung Leong
2018-12-23 21:32:28 +01:00
parent acd296c9f0
commit 1beee9bdc1
9 changed files with 93 additions and 77 deletions

View File

@@ -1,7 +1,7 @@
import { createElement } from 'react';
import { hydrate, render } from 'react-dom';
import { FrontEnd } from 'front-end';
import { routes } from 'routing';
import { routes, setPageType } from 'routing';
import WordpressDataSource from 'wordpress-data-source';
import RouteManager from 'relaks-route-manager';
import { harvest } from 'relaks-harvest';
@@ -28,6 +28,9 @@ if (typeof(window) === 'object') {
basePath: pageBasePath,
preloadingDelay: 2000,
});
routeManager.addEventListener('beforechange', (evt) => {
evt.postponeDefault(setPageType(dataSource, evt.params));
});
routeManager.activate();
await routeManager.start();

View File

@@ -9,7 +9,8 @@ class ArchivePage extends AsyncComponent {
async renderAsync(meanwhile) {
let { wp, route } = this.props;
let month = Moment(route.params.month);
let slug = route.params.slugs[0];
let month = Moment(slug);
let props = {
route,
month,

View File

@@ -8,7 +8,7 @@ class CategoryPage extends AsyncComponent {
async renderAsync(meanwhile) {
let { wp, route } = this.props;
let slug = route.params.category;
let slug = route.params.slugs[0];
let props = {
route,
};
@@ -32,7 +32,7 @@ class CategoryPageSync extends PureComponent {
<span>Categories > </span>
<span>{title}</span>
</h4>
<PostList route={route} posts={posts} />
<PostList route={route} category={category} posts={posts} />
</div>
);
}

View File

@@ -14,9 +14,8 @@ class PagePage extends AsyncComponent {
let props = {
route,
};
let slug = route.params.page;
let url = '/wp/v2/pages/';
props.page = await wp.fetchOne({ url, slug });
let slugs = route.params.slugs;
props.pages = await wp.fetchMultiple({ url: '/wp/v2/pages/', slugs });
return <PagePageSync {...props} />;
}
}
@@ -24,10 +23,10 @@ class PagePage extends AsyncComponent {
class PagePageSync extends PureComponent {
render() {
let { page } = this.props;
let { pages } = this.props;
let activePage = _.last(pages);
let title = _.get(page, 'title.rendered', '');
let content = _.get(page, 'content.rendered', '');
console.log(page);
return (
<div className="page">
<h1><HTML text={title} /></h1>

View File

@@ -1,3 +1,5 @@
let _ = require('lodash');
class Route {
constructor(routeManager) {
this.routeManager = routeManager;
@@ -10,71 +12,72 @@ class Route {
return this.routeManager.change(url, options);
}
find(name, params) {
return this.routeManager.find(name, params);
}
extractID(url) {
var si = url.lastIndexOf('/');
var ei;
if (si === url.length - 1) {
ei = si;
si = url.lastIndexOf('/', ei - 1);
}
var text = url.substring(si + 1, ei);
return parseInt(text);
find(slugs) {
return this.routeManager.find('page', { slugs });
}
}
let routes = {
'welcome': {
path: '/',
load: async (match) => {
match.params.module = await import('pages/welcome-page' /* webpackChunkName: "welcome" */);
}
},
'welcome-post': {
path: '/posts/${post}',
params: { post: String },
load: async (match) => {
match.params.module = await import('pages/welcome-post-page' /* webpackChunkName: "welcome-post" */);
}
},
'page': {
path: '/pages/${page}',
params: { page: String },
load: async (match) => {
match.params.module = await import('pages/page-page' /* webpackChunkName: "page" */);
}
},
'category': {
path: '/categories/${category}',
params: { category: String },
load: async (match) => {
match.params.module = await import('pages/category-page' /* webpackChunkName: "category" */);
}
},
'category-post': {
path: '/categories/${category}/${post}',
params: { category: String, post: String },
load: async (match) => {
match.params.module = await import('pages/category-post-page' /* webpackChunkName: "category-post" */);
}
},
'archive': {
path: '/archive/${month}',
params: { month: String },
load: async (match) => {
match.params.module = await import('pages/archive-page' /* webpackChunkName: "archive" */);
}
},
'archive-post': {
path: '/archive/${month}/${post}',
params: { month: String, post: String },
load: async (match) => {
match.params.module = await import('pages/archive-page' /* webpackChunkName: "archive-post" */);
path: {
from(path, params) {
params.slugs = path.split('/').filter(Boolean);
return true;
},
to(params) {
if (params.slugs instanceof Array) {
return `/${params.slugs.join('/')}`;
} else {
return `/`;
}
}
},
load: (match) => {
let type = match.params.pageType;
if (type) {
match.params.module = require(`pages/${type}-page`);
}
}
},
};
export { Route, routes };
async function setPageType(dataSource, params) {
let type;
let slugs = params.slugs;
if (slugs.length > 0) {
let rootSlugType = await getSlugType(dataSource, slugs[0]);
if (rootSlugType === 'page') {
type = 'page';
} else if (rootSlugType === 'category') {
if (slugs.length === 1) {
type = 'category';
} else if (slugs.length === 2) {
type = 'category-post';
}
} else if (rootSlugType === 'archive') {
if (slugs.length === 1 || slugs.length === 2) {
type = 'archive';
} else if (slugs.length === 3) {
type = 'archive-post';
}
}
}
params.pageType = type || 'welcome';
}
async function getSlugType(dataSource, slug) {
let options = {}; // { minimum: '100%' };
let pages = await dataSource.fetchList('/wp/v2/pages/?parent=0', options);
if (_.some(pages, { slug })) {
return 'page';
}
let categories = await dataSource.fetchList('/wp/v2/categories/', options);
if (_.some(categories, { slug })) {
return 'category';
}
if (/^\d{4}\-\d{2}$/.test(slug)) {
return 'archive';
}
}
export { Route, routes, setPageType };

View File

@@ -7,13 +7,23 @@ class PostListView extends PureComponent {
static displayName = 'PostListView';
render() {
let { post, author } = this.props;
let { route, category, post, author, month } = this.props;
let title = _.get(post, 'title.rendered', '');
let excerpt = _.get(post, 'excerpt.rendered', '');
excerpt = cleanExcerpt(excerpt);
let slugs = [ post.slug ];
if (category) {
slugs.unshift(category.slug);
}
if (month) {
slugs.unshift(month.format('YYYY-MM'));
}
let url = route.find(slugs);
return (
<div className="post-list-view">
<h2><HTML text={title} /></h2>
<h2>
<a href={url}><HTML text={title} /></a>
</h2>
<p><HTML text={excerpt} /></p>
</div>
);

View File

@@ -7,16 +7,16 @@ class PostList extends PureComponent {
static displayName = 'PostList'
render() {
let { posts, authors } = this.props;
let { route, posts, category, month, authors } = this.props;
if (!posts) {
return null;
}
return (
<div className="posts">
{
posts.map((post) => {
posts.map((post, i) => {
let author = _.find(authors, { id: post.author_id });
return <PostListView post={post} author={author} />
return <PostListView route={route} category={category} post={post} author={author} key={i} />
})
}
</div>

View File

@@ -137,7 +137,7 @@ class SideNavSync extends PureComponent {
let name = _.get(category, 'name', '');
let description = _.get(category, 'description', '');
let slug = _.get(category, 'slug', '');
let url = route.find('category', { category: slug });
let url = route.find([ slug ]);
return (
<li key={i}>
<a href={url} title={description}>{name}</a>
@@ -190,7 +190,7 @@ class SideNavSync extends PureComponent {
let { route } = this.props;
let url;
if (!_.isEmpty(monthEntry.posts) || _.isUndefined(monthEntry.posts)) {
url = route.find('archive', { month: monthEntry.slug });
url = route.find([ monthEntry.slug ]);
}
return (
<li key={i}>

View File

@@ -15,7 +15,7 @@ class TopNav extends AsyncComponent {
meanwhile.show(<TopNavSync {...props} />);
props.system = await wp.fetchOne('/');
meanwhile.show(<TopNavSync {...props} />);
props.pages = await wp.fetchList('/wp/v2/pages/');
props.pages = await wp.fetchList('/wp/v2/pages/?parent=0');
return <TopNavSync {...props} />;
}
}
@@ -66,7 +66,7 @@ class TopNavSync extends PureComponent {
let { route } = this.props;
let title = _.get(page, 'title.rendered');
let slug = _.get(page, 'slug');
let url = route.find('page', { page: slug });
let url = route.find([ slug ]);
return (
<div className="button" key={i}>
<a href={url}>{title}</a>