@simplepg/repo
Version:
SimplePage repository
124 lines (108 loc) • 4.2 kB
JavaScript
export function populateTemplate(templateHtml, body, targetDomain, path, { title, description } = {}, avatarPath = null) {
const parser = new DOMParser()
const templateDoc = parser.parseFromString(templateHtml, 'text/html')
const rootElem = templateDoc.getElementById('content-container')
rootElem.innerHTML = body
const populateUrl = (path) => [`https://${targetDomain}.link`, ...(path.split('/').filter(Boolean))].join('/')
const select = (name, isProp = false) => templateDoc.querySelector(`meta[${isProp ? 'property' : 'name'}="${name}"`)
const setMeta = (name, content, isProp = false) => {
select(name, isProp)?.setAttribute('content', content)
}
const titleText = title || targetDomain
const descriptionText = description || `A SimplePage by ${targetDomain}`
const url = populateUrl(path)
// HTML meta
const titleElement = templateDoc.querySelector('title')
titleElement.textContent = titleText
setMeta('description', descriptionText)
setMeta('ens-domain', targetDomain)
// set favicon
const faviconElement = templateDoc.querySelector('link[rel="icon"]')
let imageUrl = populateUrl(faviconElement.href)
if (avatarPath) {
faviconElement.setAttribute('href', avatarPath)
imageUrl = populateUrl(avatarPath)
}
let twitterCardType = 'summary'
// Check if body has any img tags and use the first one for social media
const firstImgSrc = rootElem.querySelector('img')?.getAttribute('src')
if (firstImgSrc) {
imageUrl = populateUrl(firstImgSrc)
twitterCardType = 'summary_large_image'
}
// Open Graph
setMeta('og:url', url, true)
setMeta('og:title', titleText, true)
setMeta('og:description', descriptionText, true)
if (imageUrl) setMeta('og:image', imageUrl, true)
setMeta('og:site_name', targetDomain, true)
// Twitter
setMeta('twitter:card', twitterCardType)
setMeta('twitter:domain', `${targetDomain}.link`)
setMeta('twitter:url', url)
setMeta('twitter:title', titleText)
setMeta('twitter:description', descriptionText)
if (imageUrl) setMeta('twitter:image', imageUrl)
return `<!DOCTYPE html>\n${templateDoc.documentElement.outerHTML}`;
}
export function populateManifest(domain, { title, description } = {}) {
const manifest = {
name: title || domain,
short_name: domain,
description: description || `A SimplePage by ${domain}`,
icons: [
{
src: "/_assets/images/logo.svg",
sizes: "192x192",
type: "image/svg+xml"
}
],
dapp_repository: "https://github.com/stigmergic-org/simplepage",
dapp_contracts: []
}
return JSON.stringify(manifest)
}
/**
* Extracts frontmatter from markdown content.
* Only parses title (text), description (text), and sidebar (boolean).
* @param {string} markdown - The markdown content.
* @returns {object} Object containing frontmatter data.
*/
export function parseFrontmatter(markdown) {
const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
const match = markdown.match(frontmatterRegex);
if (!match) {
return {}
}
const frontmatterLines = match[1].split('\n');
const frontmatter = {};
for (const line of frontmatterLines) {
// Skip empty lines
if (!line.trim()) continue;
// Match key: value pattern
const keyValueMatch = line.match(/^([^:]+):\s*(.*)$/);
if (keyValueMatch) {
const key = keyValueMatch[1].trim();
let value = keyValueMatch[2].trim();
// Only parse specific fields
if (key === 'title' || key === 'description') {
// Remove quotes if present
if ((value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))) {
value = value.slice(1, -1);
}
frontmatter[key] = value;
} else if (key === 'sidebar') {
// Parse as boolean
frontmatter[key] = value.toLowerCase() === 'true';
}
// Ignore all other fields
}
}
return frontmatter;
}
export function populateRedirects(pages) {
return pages.map(page => {
return `${page}* ${page} 200`
}).join('\n')
}