Last active
July 22, 2019 07:11
-
-
Save bartwttewaall/df5fd0844bb4a38f1aa520b6ffef76ad to your computer and use it in GitHub Desktop.
Generate HTML meta tags from JSON data (Twig)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { extendFunction } from "twig"; | |
/** | |
* Method for building meta tags. Insprited by: | |
* @link https://gist.github.com/rquast/a9cbc0551a48d10e83b2ad899b293c77 | |
* | |
* @example js preperation | |
const meta = { | |
page: { | |
description: | |
"Welcome to Skillkingdom, a competitive micro e-sports platform for everyone. Create an account, and dive into the battlefield with Coinbattle! Or chat and chill with your friends in the Hangout Lobby!", | |
keywords: | |
"games, io, multiplayer, Coinbattle, Skillkingdom, esports, money, gaming, browser, web browser, online, shooter, topdown, iogame, win, realtime, video games, web game, skill, kingdom, web, action, fun, friends, mmo" | |
}, | |
opengraph: { | |
"og:type": "article", | |
"og:image": "/img/og-image.png", | |
"og:image:height": 256, | |
"og:image:width": 256, | |
"og:title": "Skillkingdom - Competitive micro e-sports platform", | |
"og:site_name": "Skillkingdom", | |
"og:description": | |
"Welcome to Skillkingdom, a competitive micro e-sports platform for everyone. Create an account, and dive into the battlefield with Coinbattle! Or chat and chill with your friends in the Hangout Lobby!", | |
"og:url": "https://skillkingdom.com" | |
} | |
} | |
* | |
* @example twig implementation | |
{{ seo({page:{description:"Welcome"}}, defaultMeta) }} | |
**/ | |
extendFunction("seo", (jsonData: string | object, defaultJsonData?: string | object) => { | |
let data = typeof jsonData === "string" ? JSON.parse(jsonData as string) : jsonData; | |
if (!!defaultJsonData) { | |
const defaultData = typeof defaultJsonData === "string" ? JSON.parse(defaultJsonData as string) : defaultJsonData; | |
data = mergeDeep(defaultData, data); | |
} | |
let elements = []; | |
for (let prop in data) { | |
let transformer = TRANSFORMER_TYPES[prop]; | |
let content = data[prop]; | |
for (let key of transformer.elements) { | |
if (!content.hasOwnProperty(key)) continue; | |
elements.push(`<${transformer.type} ${transformer.key}="${key}" ${transformer.value}="${content[key]}">`); | |
} | |
} | |
return elements.join("\n"); | |
}); | |
const TRANSFORMER_TYPES = { | |
page: { | |
type: "meta", | |
key: "name", | |
value: "content", | |
elements: [ | |
"viewport", | |
"keywords", | |
"description", | |
"subject", | |
"copyright", | |
"language", | |
"robots", | |
"revised", | |
"abstract", | |
"topic", | |
"summary", | |
"Classification", | |
"author", | |
"designer", | |
"copyright", | |
"reply-to", | |
"owner", | |
"url", | |
"identifier-URL", | |
"directory", | |
"category", | |
"coverage", | |
"distribution", | |
"rating", | |
"revisit-after" | |
] | |
}, | |
opengraph: { | |
type: "meta", | |
key: "property", | |
value: "content", | |
elements: [ | |
"og:title", | |
"og:type", | |
"og:url", | |
"og:image", | |
"og:image:height", | |
"og:image:width", | |
"og:site_name", | |
"og:description", | |
"og:email", | |
"og:phone_number", | |
"og:fax_number", | |
"og:latitude", | |
"og:longitude", | |
"og:street-address", | |
"og:locality", | |
"og:region", | |
"og:postal-code", | |
"og:country-name" | |
] | |
} | |
}; | |
function mergeDeep(target, source) { | |
const isObject = (obj) => obj && typeof obj === "object"; | |
if (!isObject(target) || !isObject(source)) { | |
return source; | |
} | |
Object.keys(source).forEach((key) => { | |
const targetValue = target[key]; | |
const sourceValue = source[key]; | |
if (Array.isArray(targetValue) && Array.isArray(sourceValue)) { | |
target[key] = targetValue.concat(sourceValue); | |
} else if (isObject(targetValue) && isObject(sourceValue)) { | |
target[key] = mergeDeep(Object.assign({}, targetValue), sourceValue); | |
} else { | |
target[key] = sourceValue; | |
} | |
}); | |
return target; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment