mirror of
https://github.com/trambarhq/relaks-wordpress-example.git
synced 2025-09-24 22:41:31 +02:00
Fixed routing.
Loading data for page. Added rudimentary slug handling to data source.
This commit is contained in:
@@ -2,10 +2,10 @@ version: "2"
|
||||
services:
|
||||
db:
|
||||
image: mysql:5.7
|
||||
ports:
|
||||
- 3306:3306
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
ports:
|
||||
- 3306:3306
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: somewordpress
|
||||
MYSQL_DATABASE: wordpress
|
||||
@@ -16,8 +16,6 @@ services:
|
||||
depends_on:
|
||||
- db
|
||||
image: wordpress:latest
|
||||
ports:
|
||||
- 8888:80
|
||||
environment:
|
||||
WORDPRESS_DB_HOST: db:3306
|
||||
WORDPRESS_DB_USER: wordpress
|
||||
@@ -25,8 +23,6 @@ services:
|
||||
restart: always
|
||||
node:
|
||||
image: node:8
|
||||
ports:
|
||||
- 8080:80
|
||||
volumes:
|
||||
- ..:/opt/example
|
||||
- ./cache:/var/cache/nginx
|
||||
@@ -45,7 +41,7 @@ services:
|
||||
- ./nginx:/etc/nginx/conf.d
|
||||
- ./cache:/var/cache/nginx
|
||||
ports:
|
||||
- "8000:80"
|
||||
- 8000:80
|
||||
restart: always
|
||||
volumes:
|
||||
db_data:
|
||||
|
@@ -7,7 +7,7 @@ import RouteManager from 'relaks-route-manager';
|
||||
import { harvest } from 'relaks-harvest';
|
||||
import Relaks from 'relaks';
|
||||
|
||||
const pageBasePath = '/';
|
||||
const pageBasePath = '';
|
||||
|
||||
if (typeof(window) === 'object') {
|
||||
async function initialize(evt) {
|
||||
|
15
src/pages/archive-page.jsx
Normal file
15
src/pages/archive-page.jsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { AsyncComponent } from 'relaks';
|
||||
|
||||
class ArchivePage extends AsyncComponent {
|
||||
static displayName = 'ArchivePage';
|
||||
|
||||
async renderAsync(meanwhile) {
|
||||
return <div>Archive</div>;
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
ArchivePage as default,
|
||||
ArchivePage,
|
||||
};
|
0
src/pages/archive-post-page.jsx
Normal file
0
src/pages/archive-post-page.jsx
Normal file
@@ -1,8 +1,8 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { AsyncComponent } from 'relaks';
|
||||
|
||||
class CategoryStoryPage extends AsyncComponent {
|
||||
static displayName = 'CategoryStoryPage';
|
||||
class CategoryPostPage extends AsyncComponent {
|
||||
static displayName = 'CategoryPostPage';
|
||||
|
||||
async renderAsync(meanwhile) {
|
||||
return <div>Category > Story</div>;
|
||||
@@ -10,6 +10,6 @@ class CategoryStoryPage extends AsyncComponent {
|
||||
}
|
||||
|
||||
export {
|
||||
CategoryStoryPage as default,
|
||||
CategoryStoryPage,
|
||||
CategoryPostPage as default,
|
||||
CategoryPostPage,
|
||||
};
|
57
src/pages/page-page.jsx
Normal file
57
src/pages/page-page.jsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import _ from 'lodash';
|
||||
import React, { PureComponent } from 'react';
|
||||
import { AsyncComponent } from 'relaks';
|
||||
import { Route } from 'routing';
|
||||
import WordPress from 'wordpress';
|
||||
|
||||
import HTML from 'widgets/html';
|
||||
|
||||
class PagePage extends AsyncComponent {
|
||||
static displayName = 'PagePage';
|
||||
|
||||
async renderAsync(meanwhile) {
|
||||
let { wp, route } = this.props;
|
||||
let props = {
|
||||
route,
|
||||
};
|
||||
let slug = route.params.page;
|
||||
let url = '/wp/v2/pages/';
|
||||
props.page = await wp.fetchOne({ url, slug });
|
||||
return <PagePageSync {...props} />;
|
||||
}
|
||||
}
|
||||
|
||||
class PagePageSync extends PureComponent {
|
||||
|
||||
render() {
|
||||
let { page } = this.props;
|
||||
let title = _.get(page, 'title.rendered', '');
|
||||
let content = _.get(page, 'content.rendered', '');
|
||||
console.log(page);
|
||||
return (
|
||||
<div className="page">
|
||||
<h1><HTML text={title} /></h1>
|
||||
<HTML text={content} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const PropTypes = require('prop-types');
|
||||
|
||||
PagePage.propTypes = {
|
||||
wp: PropTypes.instanceOf(WordPress).isRequired,
|
||||
route: PropTypes.instanceOf(Route).isRequired,
|
||||
};
|
||||
PagePageSync.propTypes = {
|
||||
page: PropTypes.object,
|
||||
route: PropTypes.instanceOf(Route).isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
export {
|
||||
PagePage as default,
|
||||
PagePage,
|
||||
PagePageSync,
|
||||
};
|
0
src/pages/welcome-post-page.jsx
Normal file
0
src/pages/welcome-post-page.jsx
Normal file
@@ -27,24 +27,52 @@ class Route {
|
||||
}
|
||||
|
||||
let routes = {
|
||||
'welcome-page': {
|
||||
'welcome': {
|
||||
path: '/',
|
||||
load: async (match) => {
|
||||
match.params.module = await import('pages/welcome-page' /* webpackChunkName: "welcome" */);
|
||||
}
|
||||
},
|
||||
'category-page': {
|
||||
path: '/${category}/',
|
||||
'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" */);
|
||||
}
|
||||
},
|
||||
'story-page': {
|
||||
path: '/${category}/${slug}/',
|
||||
params: { category: String, slug: String },
|
||||
'category-post': {
|
||||
path: '/categories/${category}/${post}',
|
||||
params: { category: String, post: String },
|
||||
load: async (match) => {
|
||||
match.params.module = await import('pages/category-story-page' /* webpackChunkName: "category-story" */);
|
||||
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" */);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@@ -168,11 +168,12 @@ A {
|
||||
}
|
||||
|
||||
.page-container {
|
||||
padding-top: 11em;
|
||||
padding-top: 11.5em;
|
||||
padding-bottom: 1em;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
margin-left: 18em;
|
||||
min-height: 100vh;
|
||||
background-color: #ffffff;
|
||||
|
||||
.page {
|
||||
|
36
src/widgets/html.jsx
Normal file
36
src/widgets/html.jsx
Normal file
@@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
|
||||
function HTML(props) {
|
||||
let text = props.text;
|
||||
if (!text) {
|
||||
return null;
|
||||
}
|
||||
if (isHTML(text)) {
|
||||
let markup = { __html: text };
|
||||
return <span dangerouslySetInnerHTML={markup} />
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
function isHTML(text) {
|
||||
if (text.indexOf('<') !== -1) {
|
||||
return true;
|
||||
}
|
||||
if (text.indexOf('&') !== -1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const PropTypes = require('prop-types');
|
||||
HTML.propTypes = {
|
||||
text: PropTypes.string,
|
||||
};
|
||||
}
|
||||
|
||||
export {
|
||||
HTML as default,
|
||||
HTML,
|
||||
};
|
@@ -134,10 +134,11 @@ class SideNavSync extends PureComponent {
|
||||
}
|
||||
|
||||
renderCategory(category, i) {
|
||||
let { route } = this.props;
|
||||
let name = _.get(category, 'name', '');
|
||||
let description = _.get(category, 'description', '');
|
||||
let slug = _.get(category, 'slug', '');
|
||||
let url = '';
|
||||
let url = route.find('category', { category: slug });
|
||||
return (
|
||||
<li key={i}>
|
||||
<a href={url} title={description}>{name}</a>
|
||||
@@ -187,9 +188,10 @@ class SideNavSync extends PureComponent {
|
||||
}
|
||||
|
||||
renderMonth(monthEntry, i) {
|
||||
let { route } = this.props;
|
||||
let url;
|
||||
if (!_.isEmpty(monthEntry.posts) || _.isUndefined(monthEntry.posts)) {
|
||||
url = '#';
|
||||
url = route.find('archive', { month: monthEntry.slug });
|
||||
}
|
||||
return (
|
||||
<li key={i}>
|
||||
|
@@ -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 = '';
|
||||
let url = route.find('page', { page: slug });
|
||||
return (
|
||||
<div className="button" key={i}>
|
||||
<a href={url}>{title}</a>
|
||||
@@ -80,7 +80,7 @@ class TopNavSync extends PureComponent {
|
||||
return (
|
||||
<div className="search-bar">
|
||||
<span className="input-container">
|
||||
<input type="text" value={search} />
|
||||
<input type="text" value={search} readOnly />
|
||||
<i className="fa fa-search" />
|
||||
</span>
|
||||
</div>
|
||||
|
@@ -120,12 +120,26 @@ prototype.notifyChanges = function(changed) {
|
||||
/**
|
||||
* Fetch one object at the URL.
|
||||
*
|
||||
* @param {String} url
|
||||
* @param {String|Object} url
|
||||
* @param {Object|undefined} options
|
||||
*
|
||||
* @return {Promise<Object>}
|
||||
*/
|
||||
prototype.fetchOne = function(url, options) {
|
||||
if (url instanceof Object) {
|
||||
var pageURL = attachSlug(url.url, url.slug);
|
||||
var pageOptions = {
|
||||
afterDelete: 'remove',
|
||||
afterInsert: 'ignore',
|
||||
afterUpdate: 'replace',
|
||||
};
|
||||
for (var key in options) {
|
||||
pageOptions[key] = options[key];
|
||||
}
|
||||
return this.fetchPage(pageURL, 1, pageOptions).then(function(objects) {
|
||||
return objects[0] || null;
|
||||
});
|
||||
}
|
||||
var _this = this;
|
||||
var absURL = this.resolveURL(url);
|
||||
var props = {
|
||||
@@ -2138,6 +2152,21 @@ function attachPageNumber(url, page) {
|
||||
return url + sep + 'page=' + page;
|
||||
}
|
||||
|
||||
function attachSlug(url, slug) {
|
||||
var qi = url.indexOf('?');
|
||||
var sep = (qi === -1) ? '?' : '&';
|
||||
return url + sep + 'slug=' + encodeURI(slug);
|
||||
}
|
||||
|
||||
function attachSlugs(url, slugs) {
|
||||
var qi = url.indexOf('?');
|
||||
var sep = (qi === -1) ? '?' : '&';
|
||||
var pairs = slugs.map(function(slug) {
|
||||
return 'slug[]=' + encodeURI(slug);
|
||||
});
|
||||
return url + sep + pairs.join('&');
|
||||
}
|
||||
|
||||
function omitSearchString(url) {
|
||||
var qi = url.lastIndexOf('?');
|
||||
if (qi !== -1) {
|
||||
|
@@ -16,6 +16,7 @@ var clientConfig = {
|
||||
entry: './main',
|
||||
output: {
|
||||
path: Path.resolve('./server/www'),
|
||||
publicPath: '/',
|
||||
filename: 'app.js',
|
||||
},
|
||||
resolve: {
|
||||
@@ -106,16 +107,7 @@ if (isDevServer) {
|
||||
// config dev-server to support client-side routing
|
||||
clientConfig.devServer = {
|
||||
inline: true,
|
||||
historyApiFallback: {
|
||||
rewrites: [
|
||||
{
|
||||
from: /.*/,
|
||||
to: function(context) {
|
||||
return context.parsedUrl.pathname.replace(/.*\/(.*)$/, '/$1');
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
historyApiFallback: true,
|
||||
};
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user