Article server based
Required Sync changes!
This commit is contained in:
1 parent
6acb7ba64d
commit
be84058aba
18 files changed
+475
-114
No files matched your search
@@ -13,10 +13,8 @@ const App = ({children, menu}) => (
|
||||
</header>
|
||||
|
||||
<main className="body-wrapper__content">
|
||||
<section className="content content_thin content--padding-top--menu">
|
||||
<div className="cloud-page__body">
|
||||
{children}
|
||||
</div>
|
||||
<section className="content content_full content--padding-top--menu">
|
||||
{children}
|
||||
</section>
|
||||
</main>
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
const React = require('react')
|
||||
const getHtml = require('../lib/component').getHtml
|
||||
const dateFormat = require('../lib/date').dateFormat
|
||||
|
||||
const Head = ({url, children}) => (
|
||||
!url
|
||||
? <h1>{children}</h1>
|
||||
: <a href={url}><h2>{children}</h2></a>
|
||||
)
|
||||
|
||||
const Article = ({data, url, title, date}) => (
|
||||
<article className="article">
|
||||
<header className="article__head">
|
||||
<Head url={url}>{title}</Head>
|
||||
<p className="date">{dateFormat(date)}</p>
|
||||
</header>
|
||||
|
||||
<div className="article__body">
|
||||
{getHtml(data)}
|
||||
</div>
|
||||
</article>
|
||||
)
|
||||
|
||||
module.exports = Article
|
||||
@@ -0,0 +1,27 @@
|
||||
const React = require('react')
|
||||
const Paginator = require('./Paginator')
|
||||
const Article = require('./Article')
|
||||
|
||||
const ArticleList = ({articles, nextPage, prevPage}) => (
|
||||
<div className="content content_thin">
|
||||
{!prevPage ? null : (
|
||||
<Paginator url={`/articles/${prevPage}`} type="top"/>
|
||||
)}
|
||||
|
||||
{articles.map(article => (
|
||||
<Article
|
||||
key={article.url}
|
||||
url={article.url}
|
||||
title={article.title}
|
||||
date={article.date}
|
||||
data={article.post}
|
||||
/>
|
||||
))}
|
||||
|
||||
{!nextPage ? null : (
|
||||
<Paginator url={`/articles/${nextPage}`} type="bottom"/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
module.exports = ArticleList
|
||||
@@ -1,20 +1,24 @@
|
||||
const React = require('react')
|
||||
const getPathWithNoTrailingSlas = require('../lib/url').getPathWithNoTrailingSlash
|
||||
|
||||
const hasSubmenu = item => !!item.items
|
||||
const doDrawSubmenu = item => false //item.active && hasSubmenu(item)
|
||||
const itemUrl = url => getPathWithNoTrailingSlas(url)
|
||||
|
||||
const selectedClassName = active => active
|
||||
const selectedClassName = flag => flag
|
||||
? 'selected'
|
||||
: ''
|
||||
|
||||
const MenuItem = ({active, text, url}) => (active
|
||||
? <span>{text}</span>
|
||||
: <a href={url}>{text}</a>
|
||||
: <a href={itemUrl(url)}>{text}</a>
|
||||
)
|
||||
|
||||
const Menu = ({items}) => {
|
||||
const content = items.map((item, index) => (
|
||||
<li key={index} className={`${item.color} ${selectedClassName(item.active)}`}>
|
||||
<li key={index}
|
||||
className={`${item.color} ${selectedClassName(item.highlighted)}`}
|
||||
>
|
||||
<MenuItem {...item}/>
|
||||
{!doDrawSubmenu(item) ? null :
|
||||
<Submenu key={index} items={item.items}/>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
const React = require('react')
|
||||
const getHtml = require('../lib/component').getHtml
|
||||
|
||||
const Page = ({children}) => (
|
||||
<div className="content content_thin">
|
||||
<div className="cloud-page__body">
|
||||
{getHtml(children)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
module.exports = Page
|
||||
@@ -0,0 +1,16 @@
|
||||
const React = require('react')
|
||||
|
||||
const text = ['↑ Предыдущая страница', '↓ Следующая страница']
|
||||
const style = ['article-page-control__top', 'article-page-control__bottom']
|
||||
|
||||
const i = type => type === 'top'
|
||||
? 0
|
||||
: 1
|
||||
|
||||
const Paginator = ({url, type}) => (
|
||||
<div className={`article-page-control ${style[i(type)]}`}>
|
||||
<a href={url}>{text[i(type)]}</a>
|
||||
</div>
|
||||
)
|
||||
|
||||
module.exports = Paginator
|
||||
@@ -3,13 +3,20 @@ import {renderToStaticMarkup} from 'react-dom/server'
|
||||
|
||||
const App = require('../components/App')
|
||||
|
||||
function renderApp({menu, page}) {
|
||||
function renderApp({menu, component}) {
|
||||
const app = (
|
||||
<App menu={menu}>
|
||||
<div dangerouslySetInnerHTML={{__html: page.data}}/>
|
||||
{component}
|
||||
</App>
|
||||
)
|
||||
return renderToStaticMarkup(app)
|
||||
}
|
||||
|
||||
function getHtml(html) {
|
||||
return (
|
||||
<div dangerouslySetInnerHTML={{__html: html}}/>
|
||||
)
|
||||
}
|
||||
|
||||
exports.renderApp = renderApp
|
||||
exports.getHtml = getHtml
|
||||
@@ -0,0 +1,91 @@
|
||||
const {readFile} = require('async-file')
|
||||
const handlebars = require('handlebars')
|
||||
|
||||
const url = require('url')
|
||||
const renderApp = require('../lib/component').renderApp
|
||||
const getHtml = require('../lib/component').getHtml
|
||||
const getPathWithNoTrailingSlash = require('../lib/url').getPathWithNoTrailingSlash
|
||||
const urlToPattern = require('../lib/url').urlToPattern
|
||||
const isMatchPathPattern = require('../lib/url').isMatchPathPattern
|
||||
const isEqualPate = require('../lib/url').isEqualPath
|
||||
const {compose, any} = require('../lib/common')
|
||||
|
||||
const menuModel = require('../models/menu').default
|
||||
const config = require('../config')
|
||||
|
||||
function isActive(path, menuItem) {
|
||||
return isEqualPate(path, menuItem.url, true)
|
||||
}
|
||||
|
||||
function isHighlighted(path, menuItem) {
|
||||
return any(flatMenuItem(menuItem)
|
||||
.map(i => isMatchPathPattern(
|
||||
compose(urlToPattern, getPathWithNoTrailingSlash)(i.url),
|
||||
path,
|
||||
true
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
function flatMenuItem(item) {
|
||||
const rootUrl = item.url
|
||||
const flatUrls = items => {
|
||||
return items.map(item => ({
|
||||
...item,
|
||||
url: url.resolve(rootUrl, item.url)
|
||||
}))
|
||||
}
|
||||
|
||||
return !item.items
|
||||
? [item]
|
||||
: item.items.reduce((acc, i) => [...acc, ...compose(flatUrls, flatMenuItem)(i)], [item])
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes plain menu model and sample path and defines is an item of menu should be active
|
||||
*
|
||||
* @param path
|
||||
* @param menu
|
||||
* @return {{items}}
|
||||
*/
|
||||
function buildMenu(path, menu) {
|
||||
const items = menu.map(item => ({
|
||||
...item,
|
||||
active: isActive(path, item),
|
||||
highlighted: isHighlighted(path, item),
|
||||
}))
|
||||
return {items}
|
||||
}
|
||||
|
||||
const getTitle = meta => 'title' in meta
|
||||
? meta.title
|
||||
: 'Шлиссельбургская художественная школа'
|
||||
|
||||
const isHtml = data => typeof data === 'string'
|
||||
|
||||
async function render(path, data, meta) {
|
||||
const component = isHtml(data)
|
||||
? getHtml(data)
|
||||
: data
|
||||
|
||||
const menu = buildMenu(path, menuModel)
|
||||
const content = renderApp({menu, component})
|
||||
|
||||
const source = await readFile(config.viewMain, 'utf-8')
|
||||
const template = handlebars.compile(source)
|
||||
|
||||
const metaData = {
|
||||
...meta,
|
||||
description: 'Сайт Шлиссельбургской художественной школы',
|
||||
image: 'https://art.shlisselburg.org/entrance.jpg',
|
||||
url: `https://art.shlisselburg.org${path}`,
|
||||
}
|
||||
|
||||
return template({
|
||||
content,
|
||||
title: getTitle(meta),
|
||||
meta: metaData,
|
||||
})
|
||||
}
|
||||
|
||||
exports.render = render
|
||||
+27
-1
@@ -1,7 +1,10 @@
|
||||
function getPathWithNoTrailingSlash(path) {
|
||||
return path.charAt(path.length - 1) === '/'
|
||||
path = path.charAt(path.length - 1) === '/'
|
||||
? path.substr(0, path.length - 1)
|
||||
: path
|
||||
return path.length === 0
|
||||
? '/'
|
||||
: path
|
||||
}
|
||||
|
||||
function isEqualPath(a, b, ignoreTrailingSlash = false) {
|
||||
@@ -10,5 +13,28 @@ function isEqualPath(a, b, ignoreTrailingSlash = false) {
|
||||
: a === b
|
||||
}
|
||||
|
||||
function isMatchPathPattern(pattern, path, ignoreTrailingSlash = false) {
|
||||
const test = ignoreTrailingSlash
|
||||
? getPathWithNoTrailingSlash(path)
|
||||
: path
|
||||
return pattern.test(test)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* /article/* -> ^\/article\/[/\w\d-_]+\/?$
|
||||
*
|
||||
* @param url
|
||||
* @return {RegExp}
|
||||
*/
|
||||
function urlToPattern(url) {
|
||||
const u = url.replace('/*', '[/\\w\\d-_]+')
|
||||
const pattern = `^${u}/?$`
|
||||
|
||||
return new RegExp(pattern)
|
||||
}
|
||||
|
||||
exports.getPathWithNoTrailingSlash = getPathWithNoTrailingSlash
|
||||
exports.isMatchPathPattern = isMatchPathPattern
|
||||
exports.urlToPattern = urlToPattern
|
||||
exports.isEqualPath = isEqualPath
|
||||
+6
-7
@@ -5,13 +5,10 @@ export default [
|
||||
color: 'blue',
|
||||
items: [
|
||||
{url: '/summer-school/2017', text: 'Летние каникулы 2017'},
|
||||
{url: '/articles/*', text: 'Статьи'},
|
||||
{url: '/article/*', text: ''},
|
||||
],
|
||||
},
|
||||
{
|
||||
'text': 'События',
|
||||
'url': '/events',
|
||||
'color': 'orange'
|
||||
},
|
||||
}, ,
|
||||
{
|
||||
'text': 'Расписание',
|
||||
'url': '/schedule',
|
||||
@@ -60,7 +57,7 @@ export default [
|
||||
{
|
||||
url: '/info/',
|
||||
text: 'Сведения об образовательной организации',
|
||||
color: 'gray',
|
||||
color: 'orange',
|
||||
items: [
|
||||
{url: 'main', text: 'Основные сведения'},
|
||||
{url: 'structure', text: 'Структура и органы управления образовательной организацией'},
|
||||
@@ -75,6 +72,8 @@ export default [
|
||||
|
||||
{url: 'tools', text: 'Список рекомендованных материалов'},
|
||||
{url: 'history', text: 'История школы'},
|
||||
|
||||
{url: '*', text: ''},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
+131
-23
@@ -1,28 +1,136 @@
|
||||
import route from 'koa-route';
|
||||
import {c} from '../core/db';
|
||||
import {accepts, index} from './';
|
||||
const React = require('react')
|
||||
import {get} from 'koa-route'
|
||||
import {c} from '../core/db'
|
||||
const Article = require('../components/Article')
|
||||
const ArticleList = require('../components/ArticleList')
|
||||
const Paginator = require('../components/Paginator')
|
||||
const {render} = require('../lib/render')
|
||||
const getPathWithNoTrailingSlash = require('../lib/url').getPathWithNoTrailingSlash
|
||||
const timestamp = require('../lib/date').timestamp
|
||||
const {sortBy} = require('../utils/sort')
|
||||
const accepts = require('./index').accepts
|
||||
|
||||
async function exists(ctx, id) {
|
||||
let i = await article(id);
|
||||
return i ? true : false;
|
||||
const sortArticleByDate = sortBy(
|
||||
i => timestamp(new Date(i.date))
|
||||
)
|
||||
|
||||
const articleUrl = article => `/article/${article.id}`
|
||||
|
||||
async function findArticle(id) {
|
||||
return c('articles').findOne({id: id})
|
||||
}
|
||||
|
||||
async function article(id){
|
||||
let i = await c('events').findOne({id: id});
|
||||
if (!i) {
|
||||
i = await c('timeline').findOne({id: id});
|
||||
}
|
||||
return i;
|
||||
async function findArticlesNin(nin, skip, limit, sort) {
|
||||
return c('articles')
|
||||
.find({
|
||||
_id: {$nin: nin}
|
||||
})
|
||||
.sort(sort)
|
||||
.skip(skip)
|
||||
.limit(limit)
|
||||
.toArray()
|
||||
}
|
||||
|
||||
export default function () {
|
||||
return route.get('/article/:id', accepts({
|
||||
'text/html': index(exists),
|
||||
'text/plain': index(exists),
|
||||
'application/json': async (ctx, id) => {
|
||||
let i = await article(id);
|
||||
if (!i) ctx.status = 404;
|
||||
else ctx.body = i;
|
||||
}
|
||||
}))
|
||||
};
|
||||
async function totalArticles() {
|
||||
return c('articles')
|
||||
.find({})
|
||||
.count()
|
||||
}
|
||||
|
||||
async function findPinned(page) {
|
||||
const now = new Date()
|
||||
return page !== 1
|
||||
? []
|
||||
: await c('articles')
|
||||
.find({until: {$gte: now}})
|
||||
.sort({date: -1})
|
||||
.toArray()
|
||||
}
|
||||
|
||||
function getMeta(article) {
|
||||
return {
|
||||
title: article.title,
|
||||
}
|
||||
}
|
||||
|
||||
function getArticles(pageSize) {
|
||||
return get('/articles/:page?', async (ctx, page) => {
|
||||
const path = getPathWithNoTrailingSlash(ctx.path)
|
||||
page = parseInt(page) || 1
|
||||
|
||||
const limit = pageSize
|
||||
const skip = (page - 1) * pageSize
|
||||
|
||||
const pinnedArticles = await findPinned(page)
|
||||
const total = await totalArticles()
|
||||
const totalPages = total / pageSize
|
||||
|
||||
const id = i => i._id
|
||||
const pinnedIds = pinnedArticles.map(id)
|
||||
const articles = await findArticlesNin(pinnedIds, skip, limit, {date: -1})
|
||||
|
||||
const prevPage = page > 1
|
||||
? page - 1
|
||||
: null
|
||||
|
||||
const nextPage = page < totalPages
|
||||
? page + 1
|
||||
: null
|
||||
|
||||
const content = [
|
||||
...pinnedArticles.sort(sortArticleByDate),
|
||||
...articles
|
||||
]
|
||||
.map(article => ({
|
||||
...article,
|
||||
url: articleUrl(article),
|
||||
}))
|
||||
const Component = (
|
||||
<ArticleList
|
||||
articles={content}
|
||||
prevPage={prevPage}
|
||||
nextPage={nextPage}
|
||||
/>
|
||||
)
|
||||
|
||||
ctx.body = await render(path, Component, getMeta({title: `Статьи`}))
|
||||
})
|
||||
}
|
||||
|
||||
function getArticle() {
|
||||
return get('/article/:id', accepts({
|
||||
'text/html': async (ctx, id) => {
|
||||
const path = getPathWithNoTrailingSlash(ctx.path)
|
||||
const article = await findArticle(id)
|
||||
|
||||
if (article) {
|
||||
const Component = (
|
||||
<div className="content content_thin">
|
||||
<Article
|
||||
title={article.title}
|
||||
date={article.date}
|
||||
data={article.post}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
ctx.type = 'text/html'
|
||||
ctx.body = await render(path, Component, getMeta(article))
|
||||
} else {
|
||||
ctx.status = 404
|
||||
}
|
||||
},
|
||||
'application/json': async (ctx, id) => {
|
||||
const article = await findArticle(id)
|
||||
|
||||
if (article) {
|
||||
ctx.body = article
|
||||
} else {
|
||||
ctx.status = 404
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
exports.getArticles = getArticles
|
||||
exports.getArticle = getArticle
|
||||
@@ -0,0 +1,88 @@
|
||||
const React = require('react')
|
||||
const Article = require('../components/Article')
|
||||
const {get} = require('koa-route')
|
||||
const {c} = require('../core/db')
|
||||
const {render} = require('../lib/render')
|
||||
const getPathWithNoTrailingSlash = require('../lib/url').getPathWithNoTrailingSlash
|
||||
const timestamp = require('../lib/date').timestamp
|
||||
const {sortBy} = require('../utils/sort')
|
||||
|
||||
const sortArticleByDate = sortBy(
|
||||
i => timestamp(new Date(i.date))
|
||||
)
|
||||
|
||||
const articleUrl = article => `/article/${article.id}`
|
||||
|
||||
async function findArticlesNin(nin, skip, limit, sort) {
|
||||
return c('articles')
|
||||
.find({
|
||||
_id: {$nin: nin}
|
||||
})
|
||||
.sort(sort)
|
||||
.skip(skip)
|
||||
.limit(limit)
|
||||
.toArray()
|
||||
}
|
||||
|
||||
async function findPinned(page) {
|
||||
const now = new Date()
|
||||
return page !== 1
|
||||
? []
|
||||
: await c('articles')
|
||||
.find({until: {$gte: now}})
|
||||
.sort({date: -1})
|
||||
.toArray()
|
||||
}
|
||||
|
||||
function getComponent(path, article) {
|
||||
return (
|
||||
<Article
|
||||
url={path}
|
||||
title={article.title}
|
||||
date={article.date}
|
||||
data={article.post}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function getMeta(article) {
|
||||
return {
|
||||
title: article.title,
|
||||
}
|
||||
}
|
||||
|
||||
function getHome(pageSize) {
|
||||
return get('/', async (ctx, page) => {
|
||||
const path = getPathWithNoTrailingSlash(ctx.path) || '/'
|
||||
page = parseInt(page) || 1
|
||||
|
||||
const limit = pageSize
|
||||
const skip = (page - 1) * pageSize
|
||||
|
||||
const pinnedArticles = await findPinned(page)
|
||||
|
||||
const id = i => i._id
|
||||
const pinnedIds = pinnedArticles.map(id)
|
||||
const articles = await findArticlesNin(pinnedIds, skip, limit, {date: -1})
|
||||
|
||||
const content = [
|
||||
...pinnedArticles.sort(sortArticleByDate),
|
||||
...articles
|
||||
]
|
||||
.map(article => getComponent(articleUrl(article), article))
|
||||
const Component = (
|
||||
<div className="content content_thin">
|
||||
<div className="hudozka-title">
|
||||
<p>МБУДО</p>
|
||||
<h1>Шлиссельбургская детская художественная школа</h1>
|
||||
</div>
|
||||
|
||||
{content}
|
||||
</div>
|
||||
)
|
||||
|
||||
ctx.body = await render(path, Component, getMeta({title: 'Шлиссельбургская ДХШ'}))
|
||||
})
|
||||
}
|
||||
|
||||
exports.getHome = getHome
|
||||
@@ -1,6 +1,5 @@
|
||||
import {readFile} from 'async-file'
|
||||
import handlebars from 'handlebars'
|
||||
import route from 'koa-route'
|
||||
import compose from 'koa-compose'
|
||||
|
||||
import {map, assign} from '../utils/common'
|
||||
@@ -8,20 +7,15 @@ import {index as indexFile} from '../config'
|
||||
|
||||
import sitemap from './sitemap'
|
||||
import schedule from './schedule'
|
||||
import {getPageUrls} from '../core/pages'
|
||||
import news from './news'
|
||||
import gallery from './gallery'
|
||||
import documents from './documents'
|
||||
import teachers from './teachers'
|
||||
import events from './events'
|
||||
import articles from './articles'
|
||||
import pages from './pages'
|
||||
|
||||
let main = () => route.get('/', index())
|
||||
|
||||
export function routes(store) {
|
||||
return compose([
|
||||
main(),
|
||||
sitemap(),
|
||||
schedule(),
|
||||
news(),
|
||||
@@ -29,7 +23,6 @@ export function routes(store) {
|
||||
documents(store),
|
||||
teachers(),
|
||||
events(),
|
||||
articles(),
|
||||
pages(),
|
||||
])
|
||||
}
|
||||
|
||||
+13
-53
@@ -1,55 +1,25 @@
|
||||
const {readFile} = require('async-file')
|
||||
const handlebars = require('handlebars')
|
||||
const React = require('react')
|
||||
const Page = require('../components/Page')
|
||||
|
||||
const {get} = require('koa-route')
|
||||
const {c} = require('../core/db')
|
||||
|
||||
const url = require('url')
|
||||
const renderApp = require('../lib/component').renderApp
|
||||
const isEqualPath = require('../lib/url').isEqualPath
|
||||
const getPathWithNoTrailingSlash = require('../lib/url').getPathWithNoTrailingSlash
|
||||
const {compose, any} = require('../lib/common')
|
||||
const {render} = require('../lib/render')
|
||||
|
||||
const menuModel = require('../models/menu').default
|
||||
const config = require('../config')
|
||||
|
||||
async function getPage(path) {
|
||||
return await c('pages').findOne({url: path})
|
||||
}
|
||||
|
||||
function isActive(path, menuItem) {
|
||||
return any(flatMenuItem(menuItem)
|
||||
.map(i => isEqualPath(path, i.url, true))
|
||||
)
|
||||
}
|
||||
|
||||
function flatMenuItem(item) {
|
||||
const rootUrl = item.url
|
||||
const flatUrls = items => {
|
||||
return items.map(item => ({
|
||||
...item,
|
||||
url: url.resolve(rootUrl, item.url)
|
||||
}))
|
||||
function getPageMeta(page) {
|
||||
return {
|
||||
title: page.title,
|
||||
}
|
||||
|
||||
return !item.items
|
||||
? [item]
|
||||
: item.items.reduce((acc, i) => [...acc, ...compose(flatUrls, flatMenuItem)(i)], [item])
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes plain menu model and sample path and defines is an item of menu should be active
|
||||
*
|
||||
* @param path
|
||||
* @param menu
|
||||
* @return {{items}}
|
||||
*/
|
||||
function buildMenu(path, menu) {
|
||||
const items = menu.map(item => ({
|
||||
...item,
|
||||
active: isActive(path, item)
|
||||
}))
|
||||
return {items}
|
||||
function getComponent(page) {
|
||||
return <Page>{page.data}</Page>
|
||||
}
|
||||
|
||||
module.exports = function () {
|
||||
@@ -57,22 +27,12 @@ module.exports = function () {
|
||||
const path = getPathWithNoTrailingSlash(ctx.path)
|
||||
const page = await getPage(path)
|
||||
if (page) {
|
||||
const menu = buildMenu(path, menuModel)
|
||||
const content = renderApp({menu, page})
|
||||
|
||||
const source = await readFile(config.viewMain, 'utf-8')
|
||||
const template = handlebars.compile(source)
|
||||
|
||||
const title = page.title
|
||||
const meta = {
|
||||
title,
|
||||
description: title,
|
||||
image: 'https://art.shlisselburg.org/entrance.jpg',
|
||||
url: `https://art.shlisselburg.org${path}`,
|
||||
}
|
||||
|
||||
ctx.type = 'text/html'
|
||||
ctx.body = template({content, title, meta})
|
||||
ctx.body = await render(
|
||||
path,
|
||||
getComponent(page),
|
||||
getPageMeta(page),
|
||||
)
|
||||
} else {
|
||||
ctx.status = 404
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ import handlebars from 'handlebars'
|
||||
|
||||
const config = require('./config')
|
||||
const error = require('./middlewares/error')
|
||||
const home = require('./routes/home')
|
||||
const article = require('./routes/articles')
|
||||
|
||||
const dirPublic = path.join(__dirname, '../public')
|
||||
const dirTemplates = path.join(__dirname, 'templates')
|
||||
@@ -52,6 +54,9 @@ export default function (store) {
|
||||
app.use(queryObject())
|
||||
|
||||
app.use(error.notFound(config.view404))
|
||||
app.use(home.getHome(5))
|
||||
app.use(article.getArticles(5))
|
||||
app.use(article.getArticle())
|
||||
app.use(routes(store))
|
||||
|
||||
return Server(app.callback())
|
||||
|
||||
@@ -6,9 +6,15 @@
|
||||
&__head {
|
||||
margin-bottom: 1.25em;
|
||||
|
||||
h3 {
|
||||
h1 {
|
||||
font-size: $biggest-font-size;
|
||||
text-align: center;
|
||||
margin-bottom: $half-margin;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: $big-font-size;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.date {
|
||||
|
||||
@@ -49,12 +49,6 @@
|
||||
font-weight: bold;
|
||||
border-top: $menu-colored-mark-thickness solid $light-color;
|
||||
|
||||
a:link, a:visited {
|
||||
color: $dark-color;
|
||||
text-decoration: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.blue {
|
||||
border-top: $menu-colored-mark-thickness solid $blue-color;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
@import "variables";
|
||||
|
||||
.main-image{
|
||||
display: none;
|
||||
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
|
||||
//display: flex;
|
||||
//justify-content: center;
|
||||
//overflow: hidden;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
max-width: 1280px;
|
||||
}
|
||||
|
||||
&__content {
|
||||
min-width: 1280px;
|
||||
width: 1280px;
|
||||
}
|
||||
//&__content {
|
||||
// min-width: 1280px;
|
||||
// width: 1280px;
|
||||
//}
|
||||
}
|
||||
|
||||
@media (max-width: $mobile-width) {
|
||||
|
||||
Reference in new issue
Block a user