[www] Page refactoring: added model, creating preview, renderPage
This commit is contained in:
1 parent
9ce0fbb53d
commit
78b1526a3d
4 files changed
+153
-33
No files matched your search
@@ -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
|
||||||
@@ -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'))
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user