refactor(layout): all layout files to jsx

This commit is contained in:
ppoffice 2019-12-23 17:11:22 -05:00
parent 2dae089370
commit 8e88905c48
25 changed files with 320 additions and 189 deletions

View File

@ -1,56 +0,0 @@
<% function buildArchive(posts, year, month = null) {
const time = moment([page.year, page.month ? page.month - 1 : null].filter(i => i !== null)); %>
<div class="card widget">
<div class="card-content">
<h3 class="tag is-link">
<%= month === null ? year : time.locale(get_config('language', 'en')).format('MMMM YYYY') %>
</h3>
<div class="timeline">
<% posts.each(post => { %>
<article class="media">
<% if (has_thumbnail(post)) { %>
<a href="<%- url_for((post.link?post.link:post.path)) %>" class="media-left">
<p class="image is-64x64">
<img class="thumbnail" src="<%= get_thumbnail(post) %>" alt="<%= post.title %>">
</p>
</a>
<% } %>
<div class="media-content">
<div class="content">
<time class="has-text-grey is-size-7 is-block is-uppercase" datetime="<%= date_xml(post.date) %>"><%= date(post.date) %></time>
<a href="<%- url_for((post.link?post.link:post.path)) %>" class="title has-link-black-ter is-size-6 has-text-weight-normal"><%= post.title %></a>
<div class="level article-meta is-mobile">
<div class="level-left">
<% if (post.categories && post.categories.length) { %>
<div class="level-item is-size-7 is-uppercase">
<%- list_categories(post.categories, {
class: 'has-link-grey ',
show_count: false,
style: 'none',
separator: ' / '
}) %>
</div>
<% } %>
</div>
</div>
</div>
</div>
</article>
<% }) %>
</div>
</div>
</div>
<% }
if (!page.year) {
let years = {};
page.posts.each(p => years[p.date.year()] = null);
for (let year of Object.keys(years).sort((a, b) => b - a)) {
let posts = page.posts.filter(p => p.date.year() == year); %>
<%- buildArchive(posts, year, null) %>
<% }
} else { %>
<%- buildArchive(page.posts, page.year, page.month) %>
<% } %>
<% if (page.total > 1) { %>
<%- _partial('common/paginator') %>
<% } %>

84
layout/archive.jsx Normal file
View File

@ -0,0 +1,84 @@
'use strict';
const moment = require('moment');
const { Component, Fragment } = require('inferno');
const Paginator = require('./misc/paginator');
module.exports = class extends Component {
render() {
const { page } = this.props;
// TODO
const helper = {};
const config = {};
const { url_for, __, has_thumbnail, get_thumbnail, date_xml, date } = helper;
const language = page.lang || page.language || config.language;
function renderArticleList(posts, year, month = null) {
const time = moment([page.year, page.month ? page.month - 1 : null].filter(i => i !== null));
return <div class="card widget">
<div class="card-content">
<h3 class="tag is-link">{month === null ? year : time.locale(language).format('MMMM YYYY')}</h3>
<div class="timeline">
{posts.map(post => {
const categories = [];
post.categories.forEach((category, i) => {
categories.push(<a className="has-link-grey" href={category.url}>{category.name}</a>);
if (i < post.categories.length - 1) {
categories.push('/');
}
});
return <article class="media">
{has_thumbnail(post) ? <a href={url_for((post.link || post.path))} class="media-left">
<p class="image is-64x64">
<img class="thumbnail" src={get_thumbnail(post)} alt={post.title || get_thumbnail(post)} />
</p>
</a> : null}
<div class="media-content">
<div class="content">
<time class="has-text-grey is-size-7 is-block is-uppercase"
datetime={date_xml(post.date)}>{date(post.date)}</time>
<a class="title has-link-black-ter is-size-6 has-text-weight-normal"
href={url_for((post.link || post.path))} >{post.title}</a>
<div class="level article-meta is-mobile">
<div class="level-left">
{categories.length ? <div class="level-item is-size-7 is-uppercase">
{categories}
</div> : null}
</div>
</div>
</div>
</div>
</article>
})}
</div>
</div>
</div>;
}
let articleList;
if (!page.year) {
const years = {};
page.posts.each(p => years[p.date.year()] = null);
articleList = Object.keys(years).sort((a, b) => b - a).map(year => {
let posts = page.posts.filter(p => p.date.year() == year);
return renderArticleList(posts, year, null);
});
} else {
articleList = renderArticleList(page.posts, page.year, page.month);
}
return <Fragment>
{articleList}
{page.total > 1 ? <Paginator
current={page.current}
total={page.total}
baseUrl={page.base}
path={config.pagination_dir}
urlFor={url_for}
prevTitle={__('common.prev')}
nextTitle={__('common.next')} /> : null}
</Fragment>;
}
}

View File

@ -1,30 +0,0 @@
<% function build_list(categories) {
return categories.map(category => {
let result = `<li>
<a class="level is-marginless" href="${category.url}">
<span class="level-start">
<span class="level-item">${category.name}</span>
</span>
<span class="level-end">
<span class="level-item tag">${category.count}</span>
</span>
</a>`;
if (category.hasOwnProperty('children')) {
result += '<ul>' + build_list(category.children) + '</ul>';
}
return result + '</li>';
}).join('');
}
%>
<div class="card widget">
<div class="card-content">
<div class="menu">
<h3 class="menu-label">
<%= _p('common.category', Infinity) %>
</h3>
<ul class="menu-list">
<%- build_list(_list_categories()) %>
</ul>
</div>
</div>
</div>

14
layout/categories.jsx Normal file
View File

@ -0,0 +1,14 @@
'use strict';
const { Component } = require('inferno');
const Categories = require('./widget/categories');
module.exports = class extends Component {
render() {
const { site, page } = this.props;
// TODO
const helper = {};
return <Categories site={site} page={page} helper={helper} />;
}
}

View File

@ -1,14 +0,0 @@
<div class="card">
<div class="card-content">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><a href="<%- url_for('/categories') %>"><%= _p('common.category', Infinity) %></a></li>
<% page.parents.forEach(category => { %>
<li><a href="<%- url_for(category.path) %>"><%= category.name %></a></li>
<% }) %>
<li class="is-active"><a href="#" aria-current="page"><%= page.category %></a></li>
</ul>
</nav>
</div>
</div>
<%- _partial('index', { page }) %>

30
layout/category.jsx Normal file
View File

@ -0,0 +1,30 @@
'use strict';
const { Component, Fragment } = require('inferno');
const Index = require('./index');
module.exports = class extends Component {
render() {
const { page } = this.props;
// TODO
const helper = {};
const { url_for, _p } = helper;
return <Fragment>
<div class="card">
<div class="card-content">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><a href={url_for('/categories')}>{_p('common.category', Infinity)}</a></li>
{page.parents.map(category => {
return <li><a href={url_for(category.path)}>{category.name}</a></li>
})}
<li class="is-active"><a href="#" aria-current="page">{page.category}</a></li>
</ul>
</nav>
</div>
</div>
<Index {...this.props} />
</Fragment>;
}
}

View File

@ -7,7 +7,7 @@ const Donates = require('./donates');
const Comment = require('./comment');
/**
* Get the word count of a paragraph.
* Get the word count of text.
*/
function getWordCount(content) {
content = content.replace(/<\/?[a-z][^>]*>/gi, '');

View File

@ -21,6 +21,8 @@ module.exports = class extends Component {
highlight
} = config;
const language = page.lang || page.language || config.language;
let hlTheme, images;
if (highlight && highlight.enable === false) {
hlTheme = null;
@ -64,7 +66,7 @@ module.exports = class extends Component {
url={url}
images={page.photos || images}
siteName={config.title}
language={page.lang || page.language || config.language}
language={language}
twitterId={open_graph.twitter}
googlePlus={open_graph.google_plus}
facebookAdmins={open_graph.fb_admins}

View File

@ -66,7 +66,7 @@ class Navbar extends Component {
}
module.exports = cacheComponent(Navbar, 'common.navbar', props => {
const { config, helper, page } = this.props;
const { config, helper, page } = props;
const { url_for, _p, __ } = helper;
const { logo, title, navbar, widgets, search } = config;

22
layout/common/search.jsx Normal file
View File

@ -0,0 +1,22 @@
'use strict';
const logger = require('hexo-log');
const { Component } = require('inferno');
module.exports = class extends Component {
render() {
const { config, helper } = this.props;
const { search } = config;
if (!search || typeof search.type !== 'string') {
return null;
}
try {
const Search = require('../search/' + search.type);
return <Search config={config} helper={helper} search={search} />;
} catch (e) {
logger.warn(`Icarus cannot load search "${search.type}"`);
return null;
}
}
};

View File

@ -1,6 +0,0 @@
<% page.posts.each(function(post){ %>
<%- _partial('common/article', { post, index: true }) %>
<% }); %>
<% if (page.total > 1) { %>
<%- _partial('common/paginator') %>
<% } %>

26
layout/index.jsx Normal file
View File

@ -0,0 +1,26 @@
'use strict';
const { Component, Fragment } = require('inferno');
const Article = require('./common/article');
const Paginator = require('./misc/paginator');
module.exports = class extends Component {
render() {
const { page } = this.props;
// TODO
const helper = {};
const config = {};
return <Fragment>
{page.posts.each(post => <Article config={config} page={post} helper={helper} index={true} />)}
{page.total > 1 ? <Paginator
current={page.current}
total={page.total}
baseUrl={page.base}
path={config.pagination_dir}
urlFor={helper.url_for}
prevTitle={helper.__('common.prev')}
nextTitle={helper.__('common.next')} /> : null}
</Fragment>;
}
}

View File

@ -1,35 +0,0 @@
<!DOCTYPE html>
<html <%- has_config('language') ? ' lang="' + get_config('language').substring(0, 2) + '"' : '' %>>
<head>
<%- _partial('common/head') %>
</head>
<body class="is-<%= column_count() %>-column">
<%- _partial('common/navbar') %>
<% function main_column_class() {
switch (column_count()) {
case 1:
return 'is-12';
case 2:
return 'is-8-tablet is-8-desktop is-8-widescreen';
case 3:
return 'is-8-tablet is-8-desktop is-6-widescreen'
}
return '';
} %>
<section class="section">
<div class="container">
<div class="columns">
<div class="column <%= main_column_class() %> has-order-2 column-main"><%- body %></div>
<%- _partial('common/widget', { position: 'left' }) %>
<%- _partial('common/widget', { position: 'right' }) %>
</div>
</div>
</section>
<%- _partial('common/footer') %>
<%- _partial('common/scripts') %>
<% if (has_config('search.type')) { %>
<%- _partial('search/' + get_config('search.type')) %>
<% } %>
</body>
</html>

49
layout/layout.jsx Normal file
View File

@ -0,0 +1,49 @@
'use strict';
const { Component } = require('inferno');
const Head = require('./common/head');
const Navbar = require('./common/navbar');
const Widgets = require('./common/widgets');
const Footer = require('./common/footer');
const Scripts = require('./common/scripts');
const Search = require('./common/search');
module.exports = class extends Component {
render() {
const { env, site, page, body } = this.props;
// TODO
const helper = {};
const config = {};
const language = page.lang || page.language || config.language;
const columnCount = Widgets.getColumnCount(config.widgets);
return <html lang={language ? language.substr(0, 2) : ''}>
<head>
<Head env={env} site={site} config={config} helper={helper} page={page} />
</head>
<body class={`is-${columnCount}-column`}>
<Navbar config={config} helper={helper} page={page} />
<section class="section">
<div class="container">
<div class="columns">
<div class={{
column: true,
'has-order-2': true,
'column-main': true,
'is-12': columnCount === 1,
'is-8-tablet is-8-desktop is-8-widescreen': columnCount === 2,
'is-8-tablet is-8-desktop is-6-widescreen': columnCount === 3
}} dangerouslySetInnerHTML={{ __html: body }}></div>
<Widgets site={site} config={config} helper={helper} page={page} position={'left'} />
<Widgets site={site} config={config} helper={helper} page={page} position={'right'} />
</div>
</div>
</section>
<Footer config={config} helper={helper} />
<Scripts site={site} config={config} helper={helper} page={page} />
<Search config={config} helper={helper} />
</body>
</html>;
}
}

View File

@ -1 +0,0 @@
<%- _partial('common/article', {post: page, index: false}) %>

15
layout/page.jsx Normal file
View File

@ -0,0 +1,15 @@
'use strict';
const { Component } = require('inferno');
const Article = require('./common/article');
module.exports = class extends Component {
render() {
const { page } = this.props;
// TODO
const helper = {};
const config = {};
return <Article config={config} page={page} helper={helper} index={false} />;
}
}

View File

@ -1 +0,0 @@
<%- _partial('common/article', {post: page, index: false}) %>

15
layout/post.jsx Normal file
View File

@ -0,0 +1,15 @@
'use strict';
const { Component } = require('inferno');
const Article = require('./common/article');
module.exports = class extends Component {
render() {
const { page } = this.props;
// TODO
const helper = {};
const config = {};
return <Article config={config} page={page} helper={helper} index={false} />;
}
}

View File

@ -42,9 +42,11 @@ class Baidu extends Component {
}
module.exports = cacheComponent(Baidu, 'search.baidu', props => {
const { config, helper } = props;
return {
url: props.config.url,
hint: props.__('search.hint'),
url_for: props.url_for
url: config.url,
hint: helper.__('search.hint'),
url_for: helper.url_for
};
});

View File

@ -80,9 +80,11 @@ class Google extends Component {
}
module.exports = cacheComponent(Google, 'search.google', props => {
const { helper, search } = props;
return {
cx: props.cx,
hint: props.__('search.hint'),
url_for: props.url_for
cx: search.cx,
hint: helper.__('search.hint'),
url_for: helper.url_for
};
});

View File

@ -42,15 +42,17 @@ class Insight extends Component {
}
module.exports = cacheComponent(Insight, 'search.insight', props => {
const { helper } = props;
return {
hint: props.__('search.hint'),
hint: helper.__('search.hint'),
translation: {
posts: props.__('insight.posts'),
pages: props.__('insight.pages'),
categories: props.__('insight.categories'),
tags: props.__('insight.tags'),
untitled: props.__('insight.untitled')
posts: helper.__('insight.posts'),
pages: helper.__('insight.pages'),
categories: helper.__('insight.categories'),
tags: helper.__('insight.tags'),
untitled: helper.__('insight.untitled')
},
url_for: props.url_for
url_for: helper.url_for
};
});

View File

@ -1,11 +0,0 @@
<div class="card">
<div class="card-content">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><a href="<%- url_for('/tags') %>"><%= _p('common.tag', Infinity) %></a></li>
<li class="is-active"><a href="#" aria-current="page"><%= page.tag %></a></li>
</ul>
</nav>
</div>
</div>
<%- _partial('index', { page }) %>

27
layout/tag.jsx Normal file
View File

@ -0,0 +1,27 @@
'use strict';
const { Component, Fragment } = require('inferno');
const Index = require('./index');
module.exports = class extends Component {
render() {
const { page } = this.props;
// TODO
const helper = {};
const { url_for, _p } = helper;
return <Fragment>
<div class="card">
<div class="card-content">
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><a href={url_for('/tags')}>{_p('common.tag', Infinity)}</a></li>
<li class="is-active"><a href="#" aria-current="page">{page.tag}</a></li>
</ul>
</nav>
</div>
</div>
<Index {...this.props} />
</Fragment>;
}
}

View File

@ -1,19 +0,0 @@
<div class="card widget">
<div class="card-content">
<div class="menu">
<h3 class="menu-label">
<%= _p('common.tag', Infinity) %>
</h3>
<div class="field is-grouped is-grouped-multiline">
<% _list_tags().forEach(tag => { %>
<div class="control">
<a class="tags has-addons" href="<%= tag.url %>">
<span class="tag"><%= tag.name %></span>
<span class="tag is-grey"><%= tag.count %></span>
</a>
</div>
<% }) %>
</div>
</div>
</div>
</div>

14
layout/tags.jsx Normal file
View File

@ -0,0 +1,14 @@
'use strict';
const { Component } = require('inferno');
const Tags = require('./widget/tags');
module.exports = class extends Component {
render() {
const { site } = this.props;
// TODO
const helper = {};
return <Tags site={site} helper={helper} />;
}
}