1
0
mirror of https://git.sr.ht/~cadence/bibliogram synced 2025-12-16 11:08:49 +00:00

Create initial language support

Create support for languages, then reformat user, home, and post pages
to use it, and create en and en-us language files.
This commit is contained in:
Cadence Ember
2020-07-20 01:40:27 +12:00
parent 1f76e43446
commit 496d53f47e
22 changed files with 319 additions and 54 deletions

46
src/lang/base.js Normal file
View File

@@ -0,0 +1,46 @@
// This file was automatically generated and its contents will be overwritten later.
const data = {
"go_to_profile": "MISSING STRING: go_to_profile",
"go_to_post": "MISSING STRING: go_to_post",
"go_username_or_url": "MISSING STRING: go_username_or_url",
"go_shortcode_or_url": "MISSING STRING: go_shortcode_or_url",
"go_button": "MISSING STRING: go_button",
"about_bibliogram_header": "MISSING STRING: about_bibliogram_header",
"pug_about_bibliogram_content": locals => "MISSING TEMPLATE: pug_about_bibliogram_content",
"about_this_instance_header": "MISSING STRING: about_this_instance_header",
"onion_site_available": "MISSING STRING: onion_site_available",
"t_settings": "MISSING STRING: t_settings",
"t_privacy_policy": "MISSING STRING: t_privacy_policy",
"has_not_written_privacy_policy": "MISSING STRING: has_not_written_privacy_policy",
"instance_not_blocked": "MISSING STRING: instance_not_blocked",
"instance_partially_blocked": "MISSING STRING: instance_partially_blocked",
"instance_blocked": "MISSING STRING: instance_blocked",
"rss_enabled": "MISSING STRING: rss_enabled",
"rss_disabled": "MISSING STRING: rss_disabled",
"external_links_header": "MISSING STRING: external_links_header",
"source_link": "MISSING STRING: source_link",
"matrix_link": "MISSING STRING: matrix_link",
"instances_link": "MISSING STRING: instances_link",
"contact_link": "MISSING STRING: contact_link",
"t_featured_profiles": "MISSING STRING: t_featured_profiles",
"featured_profiles_whats_this": "MISSING STRING: featured_profiles_whats_this",
"html_featured_profiles_disclaimer": "MISSING STRING: html_featured_profiles_disclaimer",
"verified_badge_alt": "MISSING STRING: verified_badge_alt",
"verified_badge_title": "MISSING STRING: verified_badge_title",
"post_counter_label": "MISSING STRING: post_counter_label",
"outgoing_follows_counter_label": "MISSING STRING: outgoing_follows_counter_label",
"incoming_follows_counter_label": "MISSING STRING: incoming_follows_counter_label",
"t_home": "MISSING STRING: t_home",
"tab_timeline": "MISSING STRING: tab_timeline",
"tab_igtv": "MISSING STRING: tab_igtv",
"next_page_button": "MISSING STRING: next_page_button",
"next_page_button_loading": "MISSING STRING: next_page_button_loading",
"profile_is_private_notice": "MISSING STRING: profile_is_private_notice",
"no_posts_notice": "MISSING STRING: no_posts_notice",
"no_more_posts_notice": "MISSING STRING: no_more_posts_notice",
"fn_page_divider": () => "MISSING FUNCTION: fn_page_divider",
"pug_post_timestamp": locals => "MISSING TEMPLATE: pug_post_timestamp"
}
module.exports = data

3
src/lang/en-us.js Normal file
View File

@@ -0,0 +1,3 @@
const data = {...require("./en")}
module.exports = data

71
src/lang/en.js Normal file
View File

@@ -0,0 +1,71 @@
const compile = require("pug").compile
const data = {...require("./base")}
/**
* @param {string} text
*/
function pug(text) {
let lines = text.split("\n")
while (lines[0] === "") lines.shift()
const indentLevel = lines[0].match(/^\t*/)[0].length
lines = lines.map(l => l.replace(new RegExp(`^\\t{0,${indentLevel}}`), ""))
return compile(lines.join("\n"))
}
;(() => {
data.go_to_profile = "Go to profile"
data.go_to_post = "Go to post"
data.go_username_or_url = "Username or URL"
data.go_shortcode_or_url = "Shortcode or URL"
data.go_button = "Go"
data.about_bibliogram_header = "About Bibliogram"
data.pug_about_bibliogram_content = pug(`
p.
Bibliogram is a website that takes data from Instagram's public profile views and puts it into
a friendlier page that loads faster, gives downloadable images, eliminates ads,
generates RSS feeds, and doesn't urge you to sign up. #[a(href=(link_to_featured_profiles ? "#featured-profiles" : "/u/instagram")).example-link See an example.]
p.
Bibliogram does #[em not] allow you to anonymously post, like, comment, follow, or view private profiles.
It does not preserve deleted posts.
`)
data.about_this_instance_header = "About this instance"
data.onion_site_available = "Onion site available"
data.t_settings = "Settings"
data.t_privacy_policy = "Privacy policy"
data.has_not_written_privacy_policy = "Owner has not written a privacy policy"
data.instance_not_blocked = "Instance is not blocked"
data.instance_partially_blocked = "Instance is partially blocked"
data.instance_blocked = "Instance is blocked"
data.rss_disabled = "RSS feeds are disabled"
data.rss_enabled = "RSS feeds are enabled"
data.external_links_header = "External links"
data.source_link = "Code on sourcehut"
data.matrix_link = "Discussion room on Matrix"
data.instances_link = "Other Bibliogram instances"
data.contact_link = "Contact the developer"
data.t_featured_profiles = "Featured profiles"
data.featured_profiles_whats_this = "What's this?"
data.html_featured_profiles_disclaimer = pug(`
p The owner of this website personally thinks that these profiles are interesting.
p These are not endorsements from the Bibliogram project.
`)()
data.verified_badge_title = "Verified"
data.verified_badge_alt = "Verified."
data.post_counter_label = "posts"
data.outgoing_follows_counter_label = "following"
data.incoming_follows_counter_label = "followed by"
data.t_home = "Home"
data.tab_timeline = "Timeline"
data.tab_igtv = "IGTV"
data.next_page_button = "Next page"
data.next_page_button_loading = "Loading..."
data.profile_is_private_notice = "Profile is private."
data.no_posts_notice = "No posts."
data.no_more_posts_notice = "No more posts."
data.fn_page_divider = number => `Page ${number}`
data.pug_post_timestamp = pug(`
| Posted on #[time(datetime=post.date.toISOString() data-local-date)= post.getDisplayDate()].
`)
})()
module.exports = data

39
src/lang/index.js Normal file
View File

@@ -0,0 +1,39 @@
const base = require("./base")
class Lang {
constructor() {
/** @type {Map<string, import("./base")>} */
this.backing = new Map()
this.backing.set("base", require("./base"))
for (const code of ["en", "en-us"]) {
// Assign lang
const data = require(`./${code}`)
this.backing.set(code, data)
// Check properties
for (const key of Object.keys(base)) {
if (!data[key] || data[key] === base[key]) {
console.log(`[!] [${code}] ${key} was not replaced`)
}
}
}
}
/**
* @param {string} code
*/
get(code) {
if (this.backing.has(code)) {
// console.log(`[.] Getting language code ${code}`)
return this.backing.get(code)
} else {
console.log(`[!] WARNING: tried to get missing language code ${code}`)
return this.backing.get("base")
}
}
}
const lang = new Lang()
module.exports = lang

View File

@@ -0,0 +1,7 @@
// This file is a template.
const data = {
// CONTENT
}
module.exports = data

51
src/lang/utils/base.txt Normal file
View File

@@ -0,0 +1,51 @@
# Front page
# Top section
go_to_profile
go_to_post
go_username_or_url
go_shortcode_or_url
go_button
# Bottom section
about_bibliogram_header
pug_about_bibliogram_content
about_this_instance_header
onion_site_available
t_settings
t_privacy_policy
has_not_written_privacy_policy
instance_not_blocked
instance_partially_blocked
instance_blocked
rss_enabled
rss_disabled
external_links_header
source_link
matrix_link
instances_link
contact_link
t_featured_profiles
featured_profiles_whats_this
html_featured_profiles_disclaimer
# User page
verified_badge_alt
verified_badge_title
post_counter_label
outgoing_follows_counter_label
incoming_follows_counter_label
t_home
tab_timeline
tab_igtv
next_page_button
next_page_button_loading
profile_is_private_notice
no_posts_notice
no_more_posts_notice
fn_page_divider
# Post page
pug_post_timestamp

View File

@@ -0,0 +1,28 @@
const fs = require("fs").promises
const pj = require("path").join
;(async () => {
const contents = await fs.readFile(pj(__dirname, "base.txt"), "utf8")
const lines = contents.split("\n")
let template = await fs.readFile(pj(__dirname, "base.template.js"), "utf8")
template = template
.replace("// This file is a template.", "// This file was automatically generated and its contents will be overwritten later.")
.replace("// CONTENT", lines
.filter(l => l && !l.startsWith("#"))
.map(l => {
if (l.startsWith("pug_")) {
return `"${l}": locals => "MISSING TEMPLATE: ${l}"`
} else if (l.startsWith("fn_")) {
return `"${l}": () => "MISSING FUNCTION: ${l}"`
} else {
return `"${l}": "MISSING STRING: ${l}"`
}
})
.join(",\n\t")
)
await fs.writeFile(pj(__dirname, "../base.js"), template, "utf8")
console.log("base.js written.")
})()