[www] Page refactoring: added model, creating preview, renderPage

This commit is contained in:
Roman Timashev committed 2017-10-28 20:28:14 +03:00
1 parent 9ce0fbb53d
commit 78b1526a3d
4 files changed
+153 -33

No files matched your search

+93
View File
@@ -0,0 +1,93 @@
const Data = require('./Data')
const Image = require('./Image')
const Config = require('./Config')
const {find, findOne, total} = require('../lib/store')
const store = () => Data.getStore(Page)
class Page {
static async find(query, options = {}) {
const items = await find(store(), query, options)
return Promise.all(items.map(processPage))
}
static async findById(id) {
const item = await findOne(store(), {id})
return !item
? null
: processPage(item)
}
static async findByUrl(url) {
const item = await findOne(store(), {url})
return !item
? null
: processPage(item)
}
static async total(query = {}) {
return total(store(), query)
}
constructor(data) {
this.id = data.id
this.hash = data.hash
this.file = data.file
this.url = data.url
this.content = data.content
this.title = data.title
this.data = data.data
this.images = data.images
this.documents = data.documents
this.preview = data.preview
}
plain() {
return {
id: this.id,
images: this.images,
documents: this.documents,
data: this.data,
title: this.title,
content: this.content,
hash: this.hash,
file: this.file,
preview: this.preview,
url: this.url,
}
}
}
const previewFromImage = (imgs = []) => imgs.length
? imgs[0]
: null
async function resolveDefaultPreview() {
const config = await Config.findConfig()
if (!config) return null
return Image.findByFile(config.articleCardDefaultPreview)
}
async function processPage(article) {
let preview = null
const previewId = article.preview
? article.preview
: previewFromImage(article.images)
if (previewId) {
preview = await Image.findById(previewId)
} else {
preview = await resolveDefaultPreview()
}
return new Page({
...article,
preview,
})
}
module.exports = Page
+2
View File
@@ -1,4 +1,5 @@
const Data = require('./Data') const Data = require('./Data')
const Page = require('./Page')
const Article = require('./Article') const Article = require('./Article')
const Album = require('./Album') const Album = require('./Album')
const Teacher = require('./Teacher') const Teacher = require('./Teacher')
@@ -30,6 +31,7 @@ export function id(i) {
} }
function init(db) { function init(db) {
Data.setStore(Page, db.collection('pages'))
Data.setStore(Article, db.collection('articles')) Data.setStore(Article, db.collection('articles'))
Data.setStore(Album, db.collection('albums')) Data.setStore(Album, db.collection('albums'))
Data.setStore(Image, db.collection('images')) Data.setStore(Image, db.collection('images'))
+54
View File
@@ -0,0 +1,54 @@
const React = require('react')
const Page = require('../core/Page')
const ImageArtifactType = require('../core/ImageArtifactType')
const {render} = require('../lib/render')
const metaImageTypesPriority = [
ImageArtifactType.FACEBOOK,
ImageArtifactType.MEDIUM,
ImageArtifactType.BIG,
ImageArtifactType.ORIGIN,
]
function getMeta(page) {
const meta = {
title: page.title,
description: page.title,
}
if (page.preview) {
try {
const artifact = page.preview.findArtifact(metaImageTypesPriority)
meta.image = artifact.url
meta.imageWidth = artifact.width
meta.imageHeight = artifact.height
} catch (error) {
}
}
return meta
}
function getComponent(page) {
const Page = require('../components/Page')
return (
<div className="content content_thin">
<Page shareable={true}>{page.data}</Page>
</div>
)
}
async function renderPage(path) {
const page = await Page.findByUrl(path)
if (!page) return null
return render(
path,
getComponent(page),
getMeta(page),
{menuPadding: true},
)
}
exports.renderPage = renderPage
+4 -33
View File
@@ -1,43 +1,14 @@
const React = require('react') const {renderPage} = require('../render/page')
const Page = require('../components/Page')
const {get} = require('koa-route') const {get} = require('koa-route')
const {c} = require('../core/db')
const getPathWithNoTrailingSlash = require('../lib/url').getPathWithNoTrailingSlash const getPathWithNoTrailingSlash = require('../lib/url').getPathWithNoTrailingSlash
const {render} = require('../lib/render')
async function getPage(path) {
return await c('pages').findOne({url: path})
}
function getPageMeta(page) {
return {
title: page.title,
description: page.title,
}
}
function getComponent(page) {
return (
<div className="content content_thin">
<Page shareable={true}>{page.data}</Page>
</div>
)
}
module.exports = function () { module.exports = function () {
return get('*', async ctx => { return get('*', async ctx => {
const path = getPathWithNoTrailingSlash(ctx.path) const path = getPathWithNoTrailingSlash(ctx.path)
const page = await getPage(path) const body = await renderPage(path)
if (page) { if (body) {
ctx.type = 'text/html' ctx.type = 'text/html'
ctx.body = await render( ctx.body = body
path,
getComponent(page),
getPageMeta(page),
{menuPadding: true},
)
} else { } else {
ctx.status = 404 ctx.status = 404
} }