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:
@@ -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();
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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>
|
||||
);
|
||||
}
|
||||
|
@@ -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>
|
||||
|
121
src/routing.js
121
src/routing.js
@@ -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 };
|
||||
|
@@ -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>
|
||||
);
|
||||
|
@@ -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>
|
||||
|
@@ -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}>
|
||||
|
@@ -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>
|
||||
|
Reference in New Issue
Block a user