From 830bcd0f82c16b8b5f1259150a6d541a210693eb Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Fri, 11 Nov 2016 10:55:07 +0100 Subject: [PATCH] Prerender opengraph tags in the server --- client/src/index.html | 4 ++ server.js | 8 ++-- server/controllers/client.js | 85 ++++++++++++++++++++++++++++++++++++ server/controllers/index.js | 4 +- 4 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 server/controllers/client.js diff --git a/client/src/index.html b/client/src/index.html index 7ae8fc54f..aa7a6035d 100644 --- a/client/src/index.html +++ b/client/src/index.html @@ -6,6 +6,10 @@ + + + + diff --git a/server.js b/server.js index 65cf69f7d..d3d3661ad 100644 --- a/server.js +++ b/server.js @@ -69,6 +69,7 @@ app.use(expressValidator({ // API routes const apiRoute = '/api/' + constants.API_VERSION app.use(apiRoute, routes.api) +app.use('/', routes.client) // Static files app.use('/client', express.static(path.join(__dirname, '/client/dist'), { maxAge: constants.STATIC_MAX_AGE })) @@ -88,12 +89,9 @@ app.use(constants.STATIC_PATHS.WEBSEED, cors(), express.static(videosPhysicalPat const thumbnailsPhysicalPath = constants.CONFIG.STORAGE.THUMBNAILS_DIR app.use(constants.STATIC_PATHS.THUMBNAILS, express.static(thumbnailsPhysicalPath, { maxAge: constants.STATIC_MAX_AGE })) -// Client application -app.use('/videos/embed', function (req, res, next) { - res.sendFile(path.join(__dirname, 'client/dist/standalone/videos/embed.html')) -}) +// Always serve index client page app.use('/*', function (req, res, next) { - res.sendFile(path.join(__dirname, 'client/dist/index.html')) + res.sendFile(path.join(__dirname, './client/dist/index.html')) }) // ----------- Tracker ----------- diff --git a/server/controllers/client.js b/server/controllers/client.js new file mode 100644 index 000000000..68ffdbcd5 --- /dev/null +++ b/server/controllers/client.js @@ -0,0 +1,85 @@ +'use strict' + +const parallel = require('async/parallel') +const express = require('express') +const fs = require('fs') +const mongoose = require('mongoose') +const path = require('path') + +const constants = require('../initializers/constants') +const middlewares = require('../middlewares') +const validators = middlewares.validators +const validatorsVideos = validators.videos + +const Video = mongoose.model('Video') +const router = express.Router() + +const opengraphComment = '' +const embedPath = path.join(__dirname, '../../client/dist/standalone/videos/embed.html') +const indexPath = path.join(__dirname, '../../client/dist/index.html') + +// Special route that add OpenGraph tags +// Do not use a template engine for a so little thing +router.use('/videos/watch/:id', validatorsVideos.videosGet, generateWatchHtmlPage) + +router.use('/videos/embed', function (req, res, next) { + res.sendFile(embedPath) +}) + +// --------------------------------------------------------------------------- + +module.exports = router + +// --------------------------------------------------------------------------- + +function addOpenGraphTags (htmlStringPage, video) { + const thumbnailUrl = constants.CONFIG.WEBSERVER.URL + video.thumbnailPath + const videoUrl = constants.CONFIG.WEBSERVER.URL + '/videos/watch/' + + const metaTags = { + 'og:type': 'video', + 'og:title': video.name, + 'og:image': thumbnailUrl, + 'og:url': videoUrl, + 'og:description': video.description, + + 'name': video.name, + 'description': video.description, + 'image': thumbnailUrl, + + 'twitter:card': 'summary_large_image', + 'twitter:site': '@Chocobozzz', + 'twitter:title': video.name, + 'twitter:description': video.description, + 'twitter:image': thumbnailUrl + } + + let tagsString = '' + Object.keys(metaTags).forEach(function (tagName) { + const tagValue = metaTags[tagName] + + tagsString += '' + }) + + return htmlStringPage.replace(opengraphComment, tagsString) +} + +function generateWatchHtmlPage (req, res, next) { + parallel({ + file: function (callback) { + fs.readFile(indexPath, callback) + }, + + video: function (callback) { + Video.load(req.params.id, callback) + } + }, function (err, results) { + if (err) return next(err) + + const html = results.file.toString() + const video = results.video.toFormatedJSON() + + const htmlStringPageWithTags = addOpenGraphTags(html, video) + res.set('Content-Type', 'text/html; charset=UTF-8').send(htmlStringPageWithTags) + }) +} diff --git a/server/controllers/index.js b/server/controllers/index.js index 6a3f3f98f..90b481e52 100644 --- a/server/controllers/index.js +++ b/server/controllers/index.js @@ -1,7 +1,9 @@ 'use strict' const apiController = require('./api/') +const clientController = require('./client') module.exports = { - api: apiController + api: apiController, + client: clientController }