Skip to content

Instantly share code, notes, and snippets.

@bartwttewaall
Last active July 22, 2019 07:11
Show Gist options
  • Save bartwttewaall/df5fd0844bb4a38f1aa520b6ffef76ad to your computer and use it in GitHub Desktop.
Save bartwttewaall/df5fd0844bb4a38f1aa520b6ffef76ad to your computer and use it in GitHub Desktop.
Generate HTML meta tags from JSON data (Twig)
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