diff --git a/server/nginx/default.conf b/server/nginx/default.conf index 8630c67..60eb017 100644 --- a/server/nginx/default.conf +++ b/server/nginx/default.conf @@ -25,13 +25,11 @@ server { proxy_cache_min_uses 1; proxy_cache_valid 200 301 302 120m; proxy_cache_valid 404 1m; - proxy_hide_header Cache-Control; - proxy_ignore_headers Cache-Control Expires Set-Cookie; + add_header Access-Control-Allow-Origin *; add_header Cache-Control "public,max-age=0"; add_header X-Cache-Date $upstream_http_date; add_header X-Cache-Status $upstream_cache_status; - add_header Access-Control-Allow-Origin *; } } diff --git a/server/page-renderer.js b/server/page-renderer.js index ecb48a4..72bd9df 100644 --- a/server/page-renderer.js +++ b/server/page-renderer.js @@ -10,6 +10,7 @@ const HTML_TEMPLATE = `${__dirname}/client/index.html`; async function generate(path, target) { // retrieve cached JSON through Nginx + console.log(`Regenerating page: ${path}`); let host = `http://${NGINX_HOST}`; // create a fetch() that remembers the URLs used let sourceURLs = []; diff --git a/src/main.js b/src/main.js index ba759c2..25a2b64 100644 --- a/src/main.js +++ b/src/main.js @@ -31,7 +31,7 @@ if (typeof(window) === 'object') { }); routeManager.addEventListener('beforechange', (evt) => { let route = new Route(routeManager, dataSource); - evt.postponeDefault(route.setPageType(evt.params)); + evt.postponeDefault(route.setParameters(evt)); }); routeManager.activate(); await routeManager.start(); @@ -57,7 +57,6 @@ if (typeof(window) === 'object') { let mtime = await res.text(); if (mtime !== mtimeLast) { if (mtimeLast) { - console.log('changed'); dataSource.invalidate(); } mtimeLast = mtime; @@ -84,7 +83,7 @@ if (typeof(window) === 'object') { }); routeManager.addEventListener('beforechange', (evt) => { let route = new Route(routeManager, dataSource); - evt.postponeDefault(route.setPageType(evt.params)); + evt.postponeDefault(route.setParameters(evt)); }); routeManager.activate(); await routeManager.start(options.path); diff --git a/src/pages/archive-page.jsx b/src/pages/archive-page.jsx index af3841a..fff76e8 100644 --- a/src/pages/archive-page.jsx +++ b/src/pages/archive-page.jsx @@ -12,22 +12,16 @@ class ArchivePage extends AsyncComponent { async renderAsync(meanwhile) { let { wp, route } = this.props; - let { monthSlug, categorySlug } = route.params; - let month = Moment(monthSlug); + let { date } = route.params; + let month = Moment(`${date.year}-${date.month}`); let props = { route, month, }; + meanwhile.show(); let after = month.toISOString(); let before = month.clone().endOf('month').toISOString(); - meanwhile.show(); - props.categories = await wp.fetchList('/wp/v2/categories/'); - meanwhile.show(); let url = `/wp/v2/posts/?after=${after}&before=${before}`; - if (categorySlug) { - let category = _.find(props.categories, { slug: categorySlug }); - url = `/wp/v2/posts/?after=${after}&before=${before}&categories=${category.id}`; - } props.posts = await wp.fetchList(url); return ; } @@ -37,23 +31,13 @@ class ArchivePageSync extends PureComponent { static displayName = 'ArchivePageSync'; render() { - let { route, categories, posts, month } = this.props; - let { monthSlug, categorySlug } = route.params; + let { route, posts, month } = this.props; let monthLabel = month.format('MMMM YYYY'); - let monthURL = route.find([ monthSlug ]); - let trail = [ { label: 'Archive' } ]; - if (categorySlug) { - let category = _.find(categories, { slug: categorySlug }); - let categoryLabel = _.get(category, 'name', ''); - trail.push({ label: monthLabel, url: monthURL }); - trail.push({ label: categoryLabel }); - } else { - trail.push({ label: monthLabel }); - } + let trail = [ { label: 'Archive' }, { label: monthLabel } ]; return (
- +
); } @@ -67,7 +51,6 @@ if (process.env.NODE_ENV !== 'production') { route: PropTypes.instanceOf(Route), }; ArchivePageSync.propTypes = { - category: PropTypes.object, posts: PropTypes.arrayOf(PropTypes.object), month: PropTypes.instanceOf(Moment), route: PropTypes.instanceOf(Route), diff --git a/src/pages/category-page.jsx b/src/pages/category-page.jsx index 16d84b9..df275cc 100644 --- a/src/pages/category-page.jsx +++ b/src/pages/category-page.jsx @@ -1,3 +1,4 @@ +import _ from 'lodash'; import React, { PureComponent } from 'react'; import { AsyncComponent } from 'relaks'; import { Route } from 'routing'; @@ -11,14 +12,14 @@ class CategoryPage extends AsyncComponent { async renderAsync(meanwhile) { let { wp, route } = this.props; - let { categorySlug } = route.params; + let { categorySlugs } = route.params; let props = { route, }; meanwhile.show(); - props.categories = await wp.fetchList('/wp/v2/categories/'); + props.categories = await wp.fetchMultiple('/wp/v2/categories/', categorySlugs); meanwhile.show(); - let category = _.find(props.categories, { slug: categorySlug }); + let category = _.last(props.categories); props.posts = await wp.fetchList(`/wp/v2/posts/?categories=${category.id}`); return ; } @@ -29,13 +30,17 @@ class CategoryPageSync extends PureComponent { render() { let { route, posts, categories } = this.props; - let { categorySlug } = route.params; - let category = _.find(categories, { slug: categorySlug }); - let categoryLabel = _.get(category, 'name', ''); - let trail = [ - { label: 'Categories' }, - { label: categoryLabel }, - ]; + let trail = [ { label: 'Categories' } ]; + let category = _.last(categories); + for (let c of categories) { + let label = _.get(c, 'name', ''); + if (c !== category) { + let url = route.getObjectURL(c); + trail.push({ label, url }); + } else { + trail.push({ label }); + } + } return (
diff --git a/src/pages/page-page.jsx b/src/pages/page-page.jsx index 22eb5cf..2a5ea2e 100644 --- a/src/pages/page-page.jsx +++ b/src/pages/page-page.jsx @@ -14,15 +14,15 @@ class PagePage extends AsyncComponent { async renderAsync(meanwhile) { let { wp, route } = this.props; - let { pageSlug, parentPageSlugs } = route.params; + let { pageSlugs } = route.params; let props = { route, }; - props.page = await wp.fetchOne('/wp/v2/pages/', pageSlug); meanwhile.show(); - props.parentPages = await wp.fetchMultiple('/wp/v2/pages/', parentPageSlugs); + props.pages = await wp.fetchMultiple('/wp/v2/pages/', pageSlugs); meanwhile.show(); - props.childPages = await wp.fetchList(`/wp/v2/pages/?parent=${props.page.id}`, { minimum: '100%' }); + let page = _.last(props.pages); + props.childPages = await wp.fetchList(`/wp/v2/pages/?parent=${page.id}`, { minimum: '100%' }); return ; } } @@ -31,25 +31,21 @@ class PagePageSync extends PureComponent { static displayName = 'PagePageSync'; render() { - let { route, page, parentPages, childPages, transform } = this.props; + let { route, pages, childPages, transform } = this.props; + let page = _.last(pages); let trail = []; - let parents = []; - if (parentPages) { - for (let parentPage of parentPages) { - parents.push(parentPage); - - let title = _.get(parentPage, 'title.rendered', ''); - let slugs = _.map(parents, 'slug'); - let url = route.find(slugs); + for (let p of pages) { + if (p !== page) { + let title = _.get(page, 'title.rendered', ''); + let url = route.getObjectURL(p); trail.push({ label: , url }) } - parents.push(page); } return (
- +
); } diff --git a/src/pages/post-page.jsx b/src/pages/post-page.jsx index 3c11d4d..b1bf4ea 100644 --- a/src/pages/post-page.jsx +++ b/src/pages/post-page.jsx @@ -14,20 +14,16 @@ class PostPage extends AsyncComponent { async renderAsync(meanwhile) { let { wp, route } = this.props; - let { monthSlug, categorySlug, postSlug } = route.params; + let { postSlug } = route.params; let props = { route, }; - if (monthSlug) { - props.month = Moment(monthSlug); - } meanwhile.show(); - if (categorySlug) { - props.category = await wp.fetchOne('/wp/v2/categories/', categorySlug); - meanwhile.show(); - } props.post = await wp.fetchOne('/wp/v2/posts/', postSlug); meanwhile.show(); + let allCategories = await wp.fetchList('/wp/v2/categories/', { minimum: '100%' }); + props.categories = findMatchingCategories(allCategories, props.post.categories, route.history); + meanwhile.show(); props.author = await wp.fetchOne('/wp/v2/users/', props.post.author); if (!wp.ssr) { meanwhile.show(); @@ -41,36 +37,78 @@ class PostPageSync extends PureComponent { static displayName = 'PostPageSync'; render() { - let { route, month, category, post, author, comments } = this.props; - let { monthSlug, categorySlug } = route.params; - let trail = []; - if (monthSlug) { - let monthLabel = month.format('MMMM YYYY'); - let monthURL = route.find([ monthSlug ]); - trail.push({ label: 'Archive' }); - trail.push({ label: monthLabel, url: monthURL }); - } - if (categorySlug) { - let categoryLabel = _.get(category, 'name', ''); - let categoryURL; - if (monthSlug) { - categoryURL = route.find([ monthSlug, categorySlug ]); - } else { - trail.push({ label: 'Categories' }); - categoryURL = route.find([ categorySlug ]); - } - trail.push({ label: categoryLabel, url: categoryURL }); + let { route, categories, post, author, comments } = this.props; + let trail = [ { label: 'Categories' } ]; + for (let c of categories) { + let label = _.get(c, 'name', ''); + let url = route.getObjectURL(c); + trail.push({ label, url }); } return (
- +
); } } +function includeCategory(list, id, allCategories) { + let category = _.find(allCategories, { id }) + if (category) { + if (!_.includes(list, category)) { + list.push(category); + } + // add parent category as well + includeCategory(list, category.parent, allCategories); + } +} + +function findMatchingCategories(allCategories, ids, history) { + let applicable = []; + for (let id of ids) { + includeCategory(applicable, id, allCategories); + } + + let historyIndex = (c) => { + return _.findLastIndex(history, (route) => { + if (route.params.categorySlugs) { + return _.includes(route.params.categorySlugs, c.slug); + } + }); + }; + let depth = (c) => { + if (c.parent) { + let parent = _.find(allCategories, { id: c.parent }); + if (parent) { + return depth(parent) + 1; + } + } + return 0; + }; + + // order applicable categories based on how recently it was visited, + // how deep it is, and alphabetically + applicable = _.orderBy(applicable, [ historyIndex, depth, 'name' ], [ 'desc', 'desc', 'asc' ]); + let anchorCategory = _.first(applicable); + + let trail = []; + if (anchorCategory) { + // add category and its ancestors + for (let c = anchorCategory; c; c = _.find(applicable, { id: c.parent })) { + trail.unshift(c); + } + // add applicable child categories + for (let c = anchorCategory; c; c = _.find(applicable, { parent: c.id })) { + if (c !== anchorCategory) { + trail.push(c); + } + } + } + return trail; +} + if (process.env.NODE_ENV !== 'production') { const PropTypes = require('prop-types'); @@ -79,11 +117,10 @@ if (process.env.NODE_ENV !== 'production') { route: PropTypes.instanceOf(Route), }; PostPageSync.propTypes = { - category: PropTypes.object, + categories: PropTypes.arrayOf(PropTypes.object), post: PropTypes.object, author: PropTypes.object, comments: PropTypes.arrayOf(PropTypes.object), - month: PropTypes.instanceOf(Moment), route: PropTypes.instanceOf(Route), }; } diff --git a/src/routing.js b/src/routing.js index cf13506..548c79d 100644 --- a/src/routing.js +++ b/src/routing.js @@ -16,77 +16,113 @@ class Route { return this.routeManager.change(url, options); } - find(params) { - if (params instanceof Array) { - let slugs = params; - return this.routeManager.find('page', { slugs }); - } else { - return this.routeManager.find('page', params); - } + getRootURL() { + return this.composeURL({ path: '/' }); } - async setPageType(params) { - let slugs = params.slugs; - if (slugs.length > 0) { - let slugType1 = await this.getSlugType(slugs[0]); - if (slugType1 === 'page') { - params.pageType = 'page'; - params.pageSlug = _.last(slugs); - params.parentPageSlugs = _.slice(slugs, 0, -1); - } else if (slugType1 === 'category') { - if (slugs.length === 1) { - params.pageType = 'category'; - params.categorySlug = slugs[0]; - } else if (slugs.length === 2) { - params.pageType = 'post'; - params.categorySlug = slugs[0]; - params.postSlug = slugs[1]; - } - } else if (slugType1 === 'archive') { - if (slugs.length === 1) { - params.pageType = 'archive'; - params.monthSlug = slugs[0]; - } else if (slugs.length === 2) { - let slugType2 = await this.getSlugType(slugs[1]); - if (slugType2 === 'category') { - params.pageType = 'archive'; - params.monthSlug = slugs[0]; - params.categorySlug = slugs[1]; - } else { - params.pageType = 'post'; - params.monthSlug = slugs[0]; - params.postSlug = slugs[1]; - } - } else if (slugs.length === 3) { - params.pageType = 'post'; - params.monthSlug = slugs[0]; - params.categorySlug = slugs[1]; - params.postSlug = slugs[2]; - } - } - } - if (!params.pageType) { - if (params.search !== undefined) { - params.pageType = 'search'; - } else { - params.pageType = 'welcome'; - } - } + getSearchURL(search) { + return this.composeURL({ path: '/', query: { s: search } }); } - async getSlugType(slug) { - let options = { minimum: '100%' }; - let pages = await this.dataSource.fetchList('/wp/v2/pages/?parent=0', options); - if (_.some(pages, { slug })) { - return 'page'; + getArchiveURL(date) { + let { year, month } = date; + return this.composeURL({ path: `/date/${year}/${month}/` }); + } + + getObjectURL(object) { + let { siteURL } = this.params; + let url = object.link; + if (!_.startsWith(url, siteURL)) { + throw new Error(`Object URL does not match site URL`); } - let categories = await this.dataSource.fetchList('/wp/v2/categories/', options); - if (_.some(categories, { slug })) { - return 'category'; + let path = url.substr(siteURL.length); + return this.composeURL({ path }); + } + + + + composeURL(urlParts) { + let context = _.clone(this.routeManager.context); + this.routeManager.rewrite('to', urlParts, context); + return this.routeManager.compose(urlParts); + } + + async setParameters(evt) { + let params = await this.getParameters(evt.path, evt.query); + params.module = require(`pages/${params.pageType}-page`); + _.assign(evt.params, params); + } + + async getParameters(path, query) { + // get the site URL and see what the page's URL would be if it + // were on WordPress itself + let siteURL = await this.getSiteURL(); + let link = siteURL + path; + console.log(link); + + // see if it's a search + let search = query.s; + if (search) { + return { pageType: 'search', search, siteURL }; } - if (/^\d{4}\-\d{2}$/.test(slug)) { - return 'archive'; + + // see if it's pointing to the root page + if (path === '/') { + return { pageType: 'welcome', siteURL }; } + + // see if it's pointing to an archive + let date = findDate(path); + if (date) { + return { pageType: 'archive', date, siteURL }; + } + + // see if it's pointing to a post by ID + let postID = findPostID(path); + if (postID) { + let post = await this.dataSource.fetchOne('/wp/v2/posts/', postID); + if (post) { + let postSlug = post.slug; + return { pageType: 'post', postSlug, siteURL }; + } + } + + // see if it's pointing to a page + let allPages = await this.dataSource.fetchList('/wp/v2/pages/', { minimum: '100%' }); + let pageSlugs = findMatchingSlugs(allPages, link); + if (pageSlugs) { + return { pageType: 'page', pageSlugs, siteURL }; + } + + // see if it's pointing to a category + let allCategories = await this.dataSource.fetchList('/wp/v2/categories/', { minimum: '100%' }); + let categorySlugs = findMatchingSlugs(allCategories, link); + if (categorySlugs) { + return { pageType: 'category', categorySlugs, siteURL }; + } + + // see if it's pointing to a tag + let allTags = await this.dataSource.fetchList('/wp/v2/tags/', { minimum: '100%' }); + let tagSlugs = findMatchingSlugs(allTags, link); + if (tagSlugs) { + let tagSlug = tagSlugs[0]; + return { pageType: 'tag', tagSlug, siteURL }; + } + + // see if it's pointing to a post + let postSlug = _.last(_.filter(_.split(path, '/'))); + let post = await this.dataSource.fetchOne('/wp/v2/posts/', postSlug); + if (post) { + return { pageType: 'post', postSlug, siteURL }; + } + + // go to the welcome page if we can't find a match + return { pageType: 'welcome', siteURL }; + } + + async getSiteURL() { + let site = await this.dataSource.fetchOne('/'); + return _.trimEnd(site.url, '/'); } async preloadPage(params) { @@ -126,31 +162,44 @@ class Route { } } -let routes = { - 'page': { - 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 `/`; - } - } - }, - query: { - search: '${search}', - }, - load: (match) => { - let type = match.params.pageType; - if (type) { - match.params.module = require(`pages/${type}-page`); - } +function findDate(path) { + if (_.startsWith(path, '/date/')) { + path = path.substr(5); + } + let m = /^\/(\d{4})\/(\d+)\/?/.exec(path); + if (m) { + return { + year: parseInt(m[1]), + month: parseInt(m[2]), + }; + } +} + +function findPostID(path) { + if (_.startsWith(path, '/archives/')) { + let id = parseInt(path.substr(10)); + if (id === id) { + return id; } - }, + } +} + +function findMatchingSlugs(objects, link) { + let matches = []; + for (let object of objects) { + let objectLink = _.trimEnd(object.link, '/') + '/'; + if (_.startsWith(objectLink, link)) { + matches.push(object); + } + } + if (matches.length > 0) { + let slugs = _.map(_.sortBy(matches, 'link.length'), 'slug'); + return slugs; + } +} + +let routes = { + 'page': { path: '*' }, }; export { diff --git a/src/style.scss b/src/style.scss index 25f17cb..4d0fb22 100644 --- a/src/style.scss +++ b/src/style.scss @@ -30,6 +30,7 @@ A { background-color: #66023c; overflow: hidden; color: #cccccc; + padding: 0 1em 0 1em; A { opacity: 0.5; @@ -44,6 +45,10 @@ A { } } + UL { + margin-left: -1em; + } + .categories { LI { margin-top: 0.2em; diff --git a/src/widgets/page-list-view.jsx b/src/widgets/page-list-view.jsx index b1b9784..2efe169 100644 --- a/src/widgets/page-list-view.jsx +++ b/src/widgets/page-list-view.jsx @@ -8,11 +8,9 @@ class PageListView extends PureComponent { static displayName = 'PageListView'; render() { - let { route, parentPages, page } = this.props; + let { route, page } = this.props; let title = _.get(page, 'title.rendered', ''); - let parentSlugs = _.map(parentPages, 'slug'); - let slugs = _.concat(parentSlugs, page.slug); - let url = route.find(slugs); + let url = route.getObjectURL(page); return (
@@ -26,7 +24,6 @@ if (process.env.NODE_ENV !== 'production') { PageListView.propTypes = { page: PropTypes.object, - parentPages: PropTypes.arrayOf(PropTypes.object), route: PropTypes.instanceOf(Route).isRequired, }; } diff --git a/src/widgets/page-list.jsx b/src/widgets/page-list.jsx index 160409c..f27ae6b 100644 --- a/src/widgets/page-list.jsx +++ b/src/widgets/page-list.jsx @@ -8,7 +8,7 @@ class PageList extends PureComponent { static displayName = 'PageList' render() { - let { route, pages, parentPages } = this.props; + let { route, pages } = this.props; if (!pages) { return null; } @@ -18,7 +18,7 @@ class PageList extends PureComponent { pages.map((page) => { return (
  • - +
  • ); }) @@ -44,7 +44,6 @@ if (process.env.NODE_ENV !== 'production') { PageList.propTypes = { pages: PropTypes.arrayOf(PropTypes.object), - parentPages: PropTypes.arrayOf(PropTypes.object), route: PropTypes.instanceOf(Route).isRequired, }; } diff --git a/src/widgets/post-list-view.jsx b/src/widgets/post-list-view.jsx index 4a175a2..602c5cd 100644 --- a/src/widgets/post-list-view.jsx +++ b/src/widgets/post-list-view.jsx @@ -9,18 +9,11 @@ class PostListView extends PureComponent { static displayName = 'PostListView'; render() { - let { route, category, post, month } = this.props; + let { route, post } = 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); + let url = route.getObjectURL(post); return (

    @@ -44,9 +37,7 @@ if (process.env.NODE_ENV !== 'production') { const PropTypes = require('prop-types'); PostListView.propTypes = { - category: PropTypes.object, post: PropTypes.object, - month: PropTypes.instanceOf(Moment), route: PropTypes.instanceOf(Route).isRequired, }; } diff --git a/src/widgets/post-list.jsx b/src/widgets/post-list.jsx index 1937e1e..a5cddfa 100644 --- a/src/widgets/post-list.jsx +++ b/src/widgets/post-list.jsx @@ -9,7 +9,7 @@ class PostList extends PureComponent { static displayName = 'PostList' render() { - let { route, posts, categories, month, authors } = this.props; + let { route, posts } = this.props; if (!posts) { return null; } @@ -17,9 +17,7 @@ class PostList extends PureComponent {
    { posts.map((post) => { - let author = _.find(authors, { id: post.author_id }); - let category = _.find(categories, { id: post.categories[0] }); - return + return }) }
    @@ -62,8 +60,6 @@ if (process.env.NODE_ENV !== 'production') { const PropTypes = require('prop-types'); PostList.propTypes = { - categories: PropTypes.arrayOf(PropTypes.object), - month: PropTypes.instanceOf(Moment), route: PropTypes.instanceOf(Route), minimum: PropTypes.number, maximum: PropTypes.number, diff --git a/src/widgets/post-view.jsx b/src/widgets/post-view.jsx index 39e0ce2..c6a4fbb 100644 --- a/src/widgets/post-view.jsx +++ b/src/widgets/post-view.jsx @@ -8,7 +8,7 @@ class PostView extends PureComponent { static displayName = 'PostView'; render() { - let { category, post, author, transform } = this.props; + let { post, author, transform } = this.props; let title = _.get(post, 'title.rendered', ''); let content = _.get(post, 'content.rendered', ''); let date = _.get(post, 'date_gmt'); @@ -35,7 +35,6 @@ if (process.env.NODE_ENV !== 'production') { const PropTypes = require('prop-types'); PostView.propTypes = { - category: PropTypes.object, post: PropTypes.object, author: PropTypes.object, transform: PropTypes.func, diff --git a/src/widgets/side-nav.jsx b/src/widgets/side-nav.jsx index e00f887..00e2bb9 100644 --- a/src/widgets/side-nav.jsx +++ b/src/widgets/side-nav.jsx @@ -11,21 +11,13 @@ class SideNav extends AsyncComponent { constructor(props) { super(props); let { route } = this.props; - let { monthSlug } = route.params; - let selectedYear; - if (monthSlug) { - selectedYear = parseInt(monthSlug.substr(0, 4)); - } else { - selectedYear = Moment().year(); - } - this.state = { - selectedYear - }; + let { date } = route.params; + let selectedYear = _.get(date, 'year', Moment().year()); + this.state = { selectedYear }; } async renderAsync(meanwhile) { let { wp, route } = this.props; - let { monthSlug } = route.params; let { selectedYear } = this.state; let props = { route, @@ -68,7 +60,10 @@ class SideNav extends AsyncComponent { let monthEntry = { month: m + 1, label: start.format('MMMM'), - slug: start.format('YYYY-MM'), + date: { + year: start.year(), + month: start.month() + 1, + }, post: undefined, start, end, @@ -96,15 +91,7 @@ class SideNav extends AsyncComponent { // load the posts of each categories props.categoryPosts = []; for (let category of props.categories) { - let url; - if (monthSlug) { - let month = Moment(monthSlug); - let after = month.toISOString(); - let before = month.endOf('month').toISOString(); - url = `/wp/v2/posts/?after=${after}&before=${before}&categories=${category.id}`; - } else { - url = `/wp/v2/posts/?categories=${category.id}`; - } + let url = `/wp/v2/posts/?categories=${category.id}`; let posts = await wp.fetchList(url); props.categoryPosts = _.clone(props.categoryPosts); props.categoryPosts.push(posts); @@ -125,7 +112,9 @@ class SideNavSync extends PureComponent { render() { return (
    +

    Categories

    {this.renderCategories()} +

    Archives

    {this.renderArchive()}
    ) @@ -136,6 +125,8 @@ class SideNavSync extends PureComponent { if (!categories) { return null; } + // only top-level categories + categories = _.filter(categories, { parent: 0 }); // don't show categories with no post categories = _.filter(categories, 'count'); // list category with more posts first @@ -153,20 +144,16 @@ class SideNavSync extends PureComponent { renderCategory(category, i) { let { route, categoryPosts } = this.props; - let { monthSlug, categorySlug } = route.params; + let { categorySlugs } = route.params; let name = _.get(category, 'name', ''); let description = _.get(category, 'description', ''); - let slugs = [ category.slug ]; - if (monthSlug) { - slugs.unshift(monthSlug); - } - let url = route.find(slugs); + let url = route.getObjectURL(category); let posts = (categoryPosts) ? categoryPosts[i] : undefined; if (_.isEmpty(posts) && !_.isUndefined(posts)) { url = undefined; } let className; - if (categorySlug === category.slug) { + if (category.slug === _.last(categorySlugs)) { className = 'selected'; } return ( @@ -216,13 +203,13 @@ class SideNavSync extends PureComponent { renderMonth(monthEntry, i) { let { route } = this.props; - let { monthSlug } = route.params; - let url = route.find([ monthEntry.slug ]); + let { date } = route.params; + let url = route.getArchiveURL(monthEntry.date); if (_.isEmpty(monthEntry.posts) && !_.isUndefined(monthEntry.posts)) { url = undefined; } let className; - if (monthSlug === monthEntry.slug) { + if (_.isEqual(monthEntry.date, date)) { className = 'selected'; } return ( diff --git a/src/widgets/top-nav.jsx b/src/widgets/top-nav.jsx index a6141ce..8ff923e 100644 --- a/src/widgets/top-nav.jsx +++ b/src/widgets/top-nav.jsx @@ -46,7 +46,7 @@ class TopNavSync extends PureComponent { let { route, system } = this.props; let name = _.get(system, 'name', ''); let description = _.get(system, 'description', ''); - let url = route.find({}); + let url = route.getRootURL(); return (
    @@ -76,8 +76,7 @@ class TopNavSync extends PureComponent { renderPageLinkButton(page, i) { let { route } = this.props; let title = _.get(page, 'title.rendered'); - let slug = _.get(page, 'slug'); - let url = route.find([ slug ]); + let url = route.getObjectURL(page); return (
    {title} @@ -101,7 +100,7 @@ class TopNavSync extends PureComponent { performSearch = (evt) => { let { search } = this.state; let { route } = this.props; - let url = route.find({ search }); + let url = route.getSearchURL(search); let options = { replace: (route.params.pageType === 'search') };