mirror of
https://github.com/trambarhq/relaks-wordpress-example.git
synced 2025-09-25 06:51:30 +02:00
Changed to slug-based routing.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { createElement } from 'react';
|
import { createElement } from 'react';
|
||||||
import { hydrate, render } from 'react-dom';
|
import { hydrate, render } from 'react-dom';
|
||||||
import { FrontEnd } from 'front-end';
|
import { FrontEnd } from 'front-end';
|
||||||
import { routes } from 'routing';
|
import { routes, setPageType } from 'routing';
|
||||||
import WordpressDataSource from 'wordpress-data-source';
|
import WordpressDataSource from 'wordpress-data-source';
|
||||||
import RouteManager from 'relaks-route-manager';
|
import RouteManager from 'relaks-route-manager';
|
||||||
import { harvest } from 'relaks-harvest';
|
import { harvest } from 'relaks-harvest';
|
||||||
@@ -28,6 +28,9 @@ if (typeof(window) === 'object') {
|
|||||||
basePath: pageBasePath,
|
basePath: pageBasePath,
|
||||||
preloadingDelay: 2000,
|
preloadingDelay: 2000,
|
||||||
});
|
});
|
||||||
|
routeManager.addEventListener('beforechange', (evt) => {
|
||||||
|
evt.postponeDefault(setPageType(dataSource, evt.params));
|
||||||
|
});
|
||||||
routeManager.activate();
|
routeManager.activate();
|
||||||
await routeManager.start();
|
await routeManager.start();
|
||||||
|
|
||||||
|
@@ -9,7 +9,8 @@ class ArchivePage extends AsyncComponent {
|
|||||||
|
|
||||||
async renderAsync(meanwhile) {
|
async renderAsync(meanwhile) {
|
||||||
let { wp, route } = this.props;
|
let { wp, route } = this.props;
|
||||||
let month = Moment(route.params.month);
|
let slug = route.params.slugs[0];
|
||||||
|
let month = Moment(slug);
|
||||||
let props = {
|
let props = {
|
||||||
route,
|
route,
|
||||||
month,
|
month,
|
||||||
|
@@ -8,7 +8,7 @@ class CategoryPage extends AsyncComponent {
|
|||||||
|
|
||||||
async renderAsync(meanwhile) {
|
async renderAsync(meanwhile) {
|
||||||
let { wp, route } = this.props;
|
let { wp, route } = this.props;
|
||||||
let slug = route.params.category;
|
let slug = route.params.slugs[0];
|
||||||
let props = {
|
let props = {
|
||||||
route,
|
route,
|
||||||
};
|
};
|
||||||
@@ -32,7 +32,7 @@ class CategoryPageSync extends PureComponent {
|
|||||||
<span>Categories > </span>
|
<span>Categories > </span>
|
||||||
<span>{title}</span>
|
<span>{title}</span>
|
||||||
</h4>
|
</h4>
|
||||||
<PostList route={route} posts={posts} />
|
<PostList route={route} category={category} posts={posts} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -14,9 +14,8 @@ class PagePage extends AsyncComponent {
|
|||||||
let props = {
|
let props = {
|
||||||
route,
|
route,
|
||||||
};
|
};
|
||||||
let slug = route.params.page;
|
let slugs = route.params.slugs;
|
||||||
let url = '/wp/v2/pages/';
|
props.pages = await wp.fetchMultiple({ url: '/wp/v2/pages/', slugs });
|
||||||
props.page = await wp.fetchOne({ url, slug });
|
|
||||||
return <PagePageSync {...props} />;
|
return <PagePageSync {...props} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,10 +23,10 @@ class PagePage extends AsyncComponent {
|
|||||||
class PagePageSync extends PureComponent {
|
class PagePageSync extends PureComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { page } = this.props;
|
let { pages } = this.props;
|
||||||
|
let activePage = _.last(pages);
|
||||||
let title = _.get(page, 'title.rendered', '');
|
let title = _.get(page, 'title.rendered', '');
|
||||||
let content = _.get(page, 'content.rendered', '');
|
let content = _.get(page, 'content.rendered', '');
|
||||||
console.log(page);
|
|
||||||
return (
|
return (
|
||||||
<div className="page">
|
<div className="page">
|
||||||
<h1><HTML text={title} /></h1>
|
<h1><HTML text={title} /></h1>
|
||||||
|
115
src/routing.js
115
src/routing.js
@@ -1,3 +1,5 @@
|
|||||||
|
let _ = require('lodash');
|
||||||
|
|
||||||
class Route {
|
class Route {
|
||||||
constructor(routeManager) {
|
constructor(routeManager) {
|
||||||
this.routeManager = routeManager;
|
this.routeManager = routeManager;
|
||||||
@@ -10,71 +12,72 @@ class Route {
|
|||||||
return this.routeManager.change(url, options);
|
return this.routeManager.change(url, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
find(name, params) {
|
find(slugs) {
|
||||||
return this.routeManager.find(name, params);
|
return this.routeManager.find('page', { slugs });
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let routes = {
|
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': {
|
'page': {
|
||||||
path: '/pages/${page}',
|
path: {
|
||||||
params: { page: String },
|
from(path, params) {
|
||||||
load: async (match) => {
|
params.slugs = path.split('/').filter(Boolean);
|
||||||
match.params.module = await import('pages/page-page' /* webpackChunkName: "page" */);
|
return true;
|
||||||
|
},
|
||||||
|
to(params) {
|
||||||
|
if (params.slugs instanceof Array) {
|
||||||
|
return `/${params.slugs.join('/')}`;
|
||||||
|
} else {
|
||||||
|
return `/`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'category': {
|
load: (match) => {
|
||||||
path: '/categories/${category}',
|
let type = match.params.pageType;
|
||||||
params: { category: String },
|
if (type) {
|
||||||
load: async (match) => {
|
match.params.module = require(`pages/${type}-page`);
|
||||||
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" */);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
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';
|
static displayName = 'PostListView';
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { post, author } = this.props;
|
let { route, category, post, author, month } = this.props;
|
||||||
let title = _.get(post, 'title.rendered', '');
|
let title = _.get(post, 'title.rendered', '');
|
||||||
let excerpt = _.get(post, 'excerpt.rendered', '');
|
let excerpt = _.get(post, 'excerpt.rendered', '');
|
||||||
excerpt = cleanExcerpt(excerpt);
|
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 (
|
return (
|
||||||
<div className="post-list-view">
|
<div className="post-list-view">
|
||||||
<h2><HTML text={title} /></h2>
|
<h2>
|
||||||
|
<a href={url}><HTML text={title} /></a>
|
||||||
|
</h2>
|
||||||
<p><HTML text={excerpt} /></p>
|
<p><HTML text={excerpt} /></p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -7,16 +7,16 @@ class PostList extends PureComponent {
|
|||||||
static displayName = 'PostList'
|
static displayName = 'PostList'
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { posts, authors } = this.props;
|
let { route, posts, category, month, authors } = this.props;
|
||||||
if (!posts) {
|
if (!posts) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className="posts">
|
<div className="posts">
|
||||||
{
|
{
|
||||||
posts.map((post) => {
|
posts.map((post, i) => {
|
||||||
let author = _.find(authors, { id: post.author_id });
|
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>
|
</div>
|
||||||
|
@@ -137,7 +137,7 @@ class SideNavSync extends PureComponent {
|
|||||||
let name = _.get(category, 'name', '');
|
let name = _.get(category, 'name', '');
|
||||||
let description = _.get(category, 'description', '');
|
let description = _.get(category, 'description', '');
|
||||||
let slug = _.get(category, 'slug', '');
|
let slug = _.get(category, 'slug', '');
|
||||||
let url = route.find('category', { category: slug });
|
let url = route.find([ slug ]);
|
||||||
return (
|
return (
|
||||||
<li key={i}>
|
<li key={i}>
|
||||||
<a href={url} title={description}>{name}</a>
|
<a href={url} title={description}>{name}</a>
|
||||||
@@ -190,7 +190,7 @@ class SideNavSync extends PureComponent {
|
|||||||
let { route } = this.props;
|
let { route } = this.props;
|
||||||
let url;
|
let url;
|
||||||
if (!_.isEmpty(monthEntry.posts) || _.isUndefined(monthEntry.posts)) {
|
if (!_.isEmpty(monthEntry.posts) || _.isUndefined(monthEntry.posts)) {
|
||||||
url = route.find('archive', { month: monthEntry.slug });
|
url = route.find([ monthEntry.slug ]);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<li key={i}>
|
<li key={i}>
|
||||||
|
@@ -15,7 +15,7 @@ class TopNav extends AsyncComponent {
|
|||||||
meanwhile.show(<TopNavSync {...props} />);
|
meanwhile.show(<TopNavSync {...props} />);
|
||||||
props.system = await wp.fetchOne('/');
|
props.system = await wp.fetchOne('/');
|
||||||
meanwhile.show(<TopNavSync {...props} />);
|
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} />;
|
return <TopNavSync {...props} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ class TopNavSync extends PureComponent {
|
|||||||
let { route } = this.props;
|
let { route } = this.props;
|
||||||
let title = _.get(page, 'title.rendered');
|
let title = _.get(page, 'title.rendered');
|
||||||
let slug = _.get(page, 'slug');
|
let slug = _.get(page, 'slug');
|
||||||
let url = route.find('page', { page: slug });
|
let url = route.find([ slug ]);
|
||||||
return (
|
return (
|
||||||
<div className="button" key={i}>
|
<div className="button" key={i}>
|
||||||
<a href={url}>{title}</a>
|
<a href={url}>{title}</a>
|
||||||
|
Reference in New Issue
Block a user