mirror of https://gitlab.com/curben/blog
fix(open_graph): use data-src attribute in img tag
* compatibility with cloudinary (see scripts/cloudinary.js) * helper has to be registered via a function - https://github.com/hexojs/hexo/issues/1462#issuecomment-277474592 - https://github.com/hexojs/hexo/issues/743#issuecomment-168262852 - https://hexo.io/api/helper - https://github.com/hexojs/hexo/blob/master/lib/plugins/helper/open_graph.js
This commit is contained in:
parent
9daf4d98b9
commit
7ebcc03977
|
@ -24,7 +24,8 @@
|
||||||
<title><% if (title) { %><%= title %> | <% } %><%= config.title %></title>
|
<title><% if (title) { %><%= title %> | <% } %><%= config.title %></title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
<%/* Add Open Graph meta tags for easier sharing on social networking sites */%>
|
<%/* Add Open Graph meta tags for easier sharing on social networking sites */%>
|
||||||
<%- open_graph() %>
|
<%/* Modified for cloudinary compatibility */%>
|
||||||
|
<%- open_graph_cloudinary() %>
|
||||||
<% if (theme.rss) { %>
|
<% if (theme.rss) { %>
|
||||||
<link rel="alternate" href="<%- theme.rss %>" title="<%= config.title %>" type="application/atom+xml">
|
<link rel="alternate" href="<%- theme.rss %>" title="<%= config.title %>" type="application/atom+xml">
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const urlFn = require('url')
|
||||||
|
const moment = require('moment')
|
||||||
|
const { escapeHTML, htmlTag, stripHTML } = require('hexo-util')
|
||||||
|
let cheerio
|
||||||
|
|
||||||
|
function meta (name, content, escape) {
|
||||||
|
if (escape !== false && typeof content === 'string') {
|
||||||
|
content = escapeHTML(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${htmlTag('meta', {
|
||||||
|
name,
|
||||||
|
content
|
||||||
|
})}\n`
|
||||||
|
}
|
||||||
|
|
||||||
|
function og (name, content, escape) {
|
||||||
|
if (escape !== false && typeof content === 'string') {
|
||||||
|
content = escapeHTML(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${htmlTag('meta', {
|
||||||
|
property: name,
|
||||||
|
content
|
||||||
|
})}\n`
|
||||||
|
}
|
||||||
|
|
||||||
|
function openGraphHelper (options = {}) {
|
||||||
|
if (!cheerio) cheerio = require('cheerio')
|
||||||
|
|
||||||
|
const { config, page } = this
|
||||||
|
const { content } = page
|
||||||
|
let images = options.image || options.images || page.photos || []
|
||||||
|
let description = options.description || page.description || page.excerpt || content || config.description
|
||||||
|
const keywords = page.keywords || (page.tags && page.tags.length ? page.tags : undefined) || config.keywords
|
||||||
|
const title = options.title || page.title || config.title
|
||||||
|
const type = options.type || (this.is_post() ? 'article' : 'website')
|
||||||
|
const url = options.url || this.url
|
||||||
|
const siteName = options.site_name || config.title
|
||||||
|
const twitterCard = options.twitter_card || 'summary'
|
||||||
|
const updated = options.updated !== false ? options.updated || page.updated : false
|
||||||
|
const language = options.language || page.lang || page.language || config.language
|
||||||
|
let result = ''
|
||||||
|
|
||||||
|
if (!Array.isArray(images)) images = [images]
|
||||||
|
|
||||||
|
if (description) {
|
||||||
|
description = stripHTML(description).substring(0, 200)
|
||||||
|
.trim() // Remove prefixing/trailing spaces
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''')
|
||||||
|
.replace(/\n/g, ' ') // Replace new lines by spaces
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!images.length && content) {
|
||||||
|
images = images.slice()
|
||||||
|
|
||||||
|
const $ = cheerio.load(content)
|
||||||
|
|
||||||
|
$('img').each(function () {
|
||||||
|
const src = $(this).attr('data-src')
|
||||||
|
if (src) images.push(src)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (description) {
|
||||||
|
result += meta('description', description, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keywords) {
|
||||||
|
if (typeof keywords === 'string') {
|
||||||
|
result += meta('keywords', keywords)
|
||||||
|
} else if (keywords.length) {
|
||||||
|
result += meta('keywords', keywords.map(tag => {
|
||||||
|
return tag.name ? tag.name : tag
|
||||||
|
}).filter(keyword => !!keyword).join())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result += og('og:type', type)
|
||||||
|
result += og('og:title', title)
|
||||||
|
result += og('og:url', url, false)
|
||||||
|
result += og('og:site_name', siteName)
|
||||||
|
if (description) {
|
||||||
|
result += og('og:description', description, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (language) {
|
||||||
|
result += og('og:locale', language, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
images = images.map(path => {
|
||||||
|
if (!urlFn.parse(path).host) {
|
||||||
|
// resolve `path`'s absolute path relative to current page's url
|
||||||
|
// `path` can be both absolute (starts with `/`) or relative.
|
||||||
|
return urlFn.resolve(url || config.url, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
return path
|
||||||
|
})
|
||||||
|
|
||||||
|
images.forEach(path => {
|
||||||
|
result += og('og:image', path, false)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (updated) {
|
||||||
|
if ((moment.isMoment(updated) || moment.isDate(updated)) && !isNaN(updated.valueOf())) {
|
||||||
|
result += og('og:updated_time', updated.toISOString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result += meta('twitter:card', twitterCard)
|
||||||
|
result += meta('twitter:title', title)
|
||||||
|
if (description) {
|
||||||
|
result += meta('twitter:description', description, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (images.length) {
|
||||||
|
result += meta('twitter:image', images[0], false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.twitter_id) {
|
||||||
|
let twitterId = options.twitter_id
|
||||||
|
if (twitterId[0] !== '@') twitterId = `@${twitterId}`
|
||||||
|
|
||||||
|
result += meta('twitter:creator', twitterId)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.twitter_site) {
|
||||||
|
result += meta('twitter:site', options.twitter_site, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.google_plus) {
|
||||||
|
result += `${htmlTag('link', { rel: 'publisher', href: options.google_plus })}\n`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.fb_admins) {
|
||||||
|
result += og('fb:admins', options.fb_admins)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.fb_app_id) {
|
||||||
|
result += og('fb:app_id', options.fb_app_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
hexo.extend.helper.register('open_graph_cloudinary', openGraphHelper)
|
Loading…
Reference in New Issue