refactor: gather firebase templates

This commit is contained in:
ZhenShuo Leo
2026-02-05 21:44:07 +08:00
parent 506740b1cf
commit 0e9a151ce5
10 changed files with 269 additions and 283 deletions
+208
View File
@@ -0,0 +1,208 @@
const pageScriptElement = document.currentScript;
const configEl = document.getElementById("firebase-config");
if (!configEl?.textContent) {
console.error("Firebase config element not found");
document
.querySelectorAll(
'[id^="views_"], [id^="likes_"], #button_likes_heart, #button_likes_emtpty_heart, #button_likes_text',
)
.forEach((el) => el.remove());
} else {
const data = JSON.parse(configEl.textContent);
const oid = data.oids?.views;
const oid_likes = data.oids?.likes;
let liked_page = false;
const id = oid ? oid.replaceAll("/", "-") : oid;
const id_likes = oid_likes ? oid_likes.replaceAll("/", "-") : oid_likes;
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function toggleLoaders(node) {
var classesString = node.className;
if (classesString == "") return;
var classes = classesString.split(" ");
for (var i in classes) {
node.classList.toggle(classes[i]);
}
}
var update_views = function (node, id) {
db.collection("views")
.doc(id)
.onSnapshot((doc) => {
var data = doc.data();
if (data) {
node.innerText = numberWithCommas(data.views);
} else {
node.innerText = 0;
}
toggleLoaders(node);
});
};
var update_likes = function (node, id) {
db.collection("likes")
.doc(id)
.onSnapshot((doc) => {
var data = doc.data();
if (data) {
node.innerText = numberWithCommas(data.likes);
} else {
node.innerText = 0;
}
toggleLoaders(node);
});
};
if (typeof auth !== "undefined") {
const viewed = localStorage.getItem(id);
if (!viewed && id) {
auth
.signInAnonymously()
.then(() => {
const docRef = db.collection("views").doc(id);
localStorage.setItem(id, true);
docRef
.get()
.then((doc) => {
if (doc.exists) {
db.collection("views")
.doc(id)
.update({
views: firebase.firestore.FieldValue.increment(1),
});
} else {
db.collection("views").doc(id).set({ views: 1 });
}
})
.catch((error) => {
console.log("Error getting document:", error);
});
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
console.error(errorCode, errorMessage);
});
}
const liked = localStorage.getItem(id_likes);
if (liked) {
liked_page = true;
document.querySelectorAll("span[id='button_likes_heart']")[0].style.display = "";
document.querySelectorAll("span[id='button_likes_emtpty_heart']")[0].style.display = "none";
document.querySelectorAll("span[id='button_likes_text']")[0].innerText = "";
}
auth
.signInAnonymously()
.then(() => {
var views_nodes = document.querySelectorAll("span[id^='views_']");
for (var i in views_nodes) {
var node = views_nodes[i];
var id = node.id ? node.id.replaceAll("/", "-") : node.id;
if (id) {
update_views(node, id);
}
}
var likes_nodes = document.querySelectorAll("span[id^='likes_']");
for (var i in likes_nodes) {
var node = likes_nodes[i];
var id = node.id ? node.id.replaceAll("/", "-") : node.id;
if (id) {
update_likes(node, id);
}
}
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.error(errorCode, errorMessage);
});
}
function like_article(id_likes) {
auth
.signInAnonymously()
.then(() => {
const docRef = db.collection("likes").doc(id_likes);
docRef
.get()
.then((doc) => {
liked_page = true;
localStorage.setItem(id_likes, true);
document.querySelectorAll("span[id='button_likes_heart']")[0].style.display = "";
document.querySelectorAll("span[id='button_likes_emtpty_heart']")[0].style.display = "none";
document.querySelectorAll("span[id='button_likes_text']")[0].innerText = "";
if (doc.exists) {
db.collection("likes")
.doc(id_likes)
.update({
likes: firebase.firestore.FieldValue.increment(1),
});
} else {
db.collection("likes").doc(id_likes).set({ likes: 1 });
}
})
.catch((error) => {
console.log("Error getting document:", error);
});
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
console.error(errorCode, errorMessage);
});
}
function remove_like_article(id_likes) {
auth
.signInAnonymously()
.then(() => {
const docRef = db.collection("likes").doc(id_likes);
docRef
.get()
.then((doc) => {
liked_page = false;
localStorage.removeItem(id_likes);
document.querySelectorAll("span[id='button_likes_heart']")[0].style.display = "none";
document.querySelectorAll("span[id='button_likes_emtpty_heart']")[0].style.display = "";
document.querySelectorAll("span[id='button_likes_text']")[0].innerText = "\xa0Like";
if (doc.exists) {
db.collection("likes")
.doc(id_likes)
.update({
likes: firebase.firestore.FieldValue.increment(-1),
});
} else {
db.collection("likes").doc(id_likes).set({ likes: 0 });
}
})
.catch((error) => {
console.log("Error getting document:", error);
});
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
console.error(errorCode, errorMessage);
});
}
window.process_article = function () {
if (!liked_page) {
like_article(id_likes);
} else {
remove_like_article(id_likes);
}
};
}
-131
View File
@@ -1,131 +0,0 @@
const pageScriptElement = document.currentScript;
const oid =
pageScriptElement && pageScriptElement.getAttribute("data-oid")
? pageScriptElement.getAttribute("data-oid")
: (console.error("data-oid is null"), null);
const oid_likes =
pageScriptElement && pageScriptElement.getAttribute("data-oid-likes")
? pageScriptElement.getAttribute("data-oid-likes")
: (console.error("data-oid-likes is null"), null);
let liked_page = false;
const id = oid ? oid.replaceAll("/", "-") : oid;
const id_likes = oid_likes ? oid_likes.replaceAll("/", "-") : oid_likes;
if (typeof auth !== "undefined") {
const viewed = localStorage.getItem(id);
if (!viewed) {
auth
.signInAnonymously()
.then(() => {
const docRef = db.collection("views").doc(id);
localStorage.setItem(id, true);
docRef
.get()
.then((doc) => {
if (doc.exists) {
db.collection("views")
.doc(id)
.update({
views: firebase.firestore.FieldValue.increment(1),
});
} else {
db.collection("views").doc(id).set({ views: 1 });
}
})
.catch((error) => {
console.log("Error getting document:", error);
});
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
console.error(errorCode, errorMessage);
});
}
const liked = localStorage.getItem(id_likes);
if (liked) {
liked_page = true;
document.querySelectorAll("span[id='button_likes_heart']")[0].style.display = "";
document.querySelectorAll("span[id='button_likes_emtpty_heart']")[0].style.display = "none";
document.querySelectorAll("span[id='button_likes_text']")[0].innerText = "";
}
}
function like_article(id_likes) {
auth
.signInAnonymously()
.then(() => {
const docRef = db.collection("likes").doc(id_likes);
docRef
.get()
.then((doc) => {
liked_page = true;
localStorage.setItem(id_likes, true);
document.querySelectorAll("span[id='button_likes_heart']")[0].style.display = "";
document.querySelectorAll("span[id='button_likes_emtpty_heart']")[0].style.display = "none";
document.querySelectorAll("span[id='button_likes_text']")[0].innerText = "";
if (doc.exists) {
db.collection("likes")
.doc(id_likes)
.update({
likes: firebase.firestore.FieldValue.increment(1),
});
} else {
db.collection("likes").doc(id_likes).set({ likes: 1 });
}
})
.catch((error) => {
console.log("Error getting document:", error);
});
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
console.error(errorCode, errorMessage);
});
}
function remove_like_article(id_likes) {
auth
.signInAnonymously()
.then(() => {
const docRef = db.collection("likes").doc(id_likes);
docRef
.get()
.then((doc) => {
liked_page = false;
localStorage.removeItem(id_likes);
document.querySelectorAll("span[id='button_likes_heart']")[0].style.display = "none";
document.querySelectorAll("span[id='button_likes_emtpty_heart']")[0].style.display = "";
document.querySelectorAll("span[id='button_likes_text']")[0].innerText = "\xa0Like";
if (doc.exists) {
db.collection("likes")
.doc(id_likes)
.update({
likes: firebase.firestore.FieldValue.increment(-1),
});
} else {
db.collection("likes").doc(id_likes).set({ likes: 0 });
}
})
.catch((error) => {
console.log("Error getting document:", error);
});
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
console.error(errorCode, errorMessage);
});
}
function process_article() {
if (!liked_page) {
like_article(id_likes);
} else {
remove_like_article(id_likes);
}
}
-70
View File
@@ -1,70 +0,0 @@
if (typeof auth !== "undefined") {
var viewsCollection = db.collection("views");
var likesCollection = db.collection("likes");
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function toggleLoaders(node) {
var classesString = node.className;
if (classesString == "") return;
var classes = classesString.split(" ");
for (var i in classes) {
node.classList.toggle(classes[i]);
}
}
var update_views = function (node, id) {
viewsCollection.doc(id).onSnapshot((doc) => {
var data = doc.data();
if (data) {
node.innerText = numberWithCommas(data.views);
} else {
node.innerText = 0;
}
toggleLoaders(node);
});
};
var update_likes = function (node, id) {
likesCollection.doc(id).onSnapshot((doc) => {
var data = doc.data();
if (data) {
node.innerText = numberWithCommas(data.likes);
} else {
node.innerText = 0;
}
toggleLoaders(node);
});
};
auth
.signInAnonymously()
.then(() => {
var views_nodes = document.querySelectorAll("span[id^='views_']");
for (var i in views_nodes) {
var node = views_nodes[i];
var id = node.id ? node.id.replaceAll("/", "-") : node.id;
if (id) {
update_views(node, id);
}
}
var likes_nodes = document.querySelectorAll("span[id^='likes_']");
for (var i in likes_nodes) {
var node = likes_nodes[i];
var id = node.id ? node.id.replaceAll("/", "-") : node.id;
if (id) {
update_likes(node, id);
}
}
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.error(errorCode, errorMessage);
});
}
-16
View File
@@ -22,22 +22,6 @@
<div class="mt-1 mb-2 text-base text-neutral-500 dark:text-neutral-400 print:hidden">
{{ partial "article-meta/list.html" (dict "context" . "scope" "single") }}
</div>
{{ $translations := .AllTranslations }}
{{ with .File }}
{{ $path := .Path }}
{{ range $translations }}
{{ $lang := print "." .Lang ".md" }}
{{ $path = replace $path $lang ".md" }}
{{ end }}
{{ $jsPage := resources.Get "js/page.js" }}
{{ $jsPage = $jsPage | resources.Minify | resources.Fingerprint (site.Params.fingerprintAlgorithm | default "sha512") }}
<script
type="text/javascript"
src="{{ $jsPage.RelPermalink }}"
integrity="{{ $jsPage.Data.Integrity }}"
data-oid="views_{{ $path }}"
data-oid-likes="likes_{{ $path }}"></script>
{{ end }}
</header>
{{/* Description (markdown content) */}}
-17
View File
@@ -68,23 +68,6 @@
{{ partial "sharing-links.html" . }}
{{ partial "related.html" . }}
</div>
{{ $translations := .AllTranslations }}
{{ with .File }}
{{ $path := .Path }}
{{ range $translations }}
{{ $lang := print "." .Lang ".md" }}
{{ $path = replace $path $lang ".md" }}
{{ end }}
{{ $jsPage := resources.Get "js/page.js" }}
{{ $jsPage = $jsPage | resources.Minify | resources.Fingerprint (site.Params.fingerprintAlgorithm | default "sha512") }}
<script
type="text/javascript"
src="{{ $jsPage.RelPermalink }}"
integrity="{{ $jsPage.Data.Integrity }}"
data-oid="views_{{ $path }}"
data-oid-likes="likes_{{ $path }}"></script>
{{ end }}
</section>
{{/* Footer */}}
-8
View File
@@ -26,14 +26,6 @@
<div class="min-w-0 min-h-0 max-w-prose">
{{ .Content }}
</div>
{{ $jsPage := resources.Get "js/page.js" }}
{{ $jsPage = $jsPage | resources.Minify | resources.Fingerprint (site.Params.fingerprintAlgorithm | default "sha512") }}
<script
type="text/javascript"
src="{{ $jsPage.RelPermalink }}"
integrity="{{ $jsPage.Data.Integrity }}"
data-oid="views_term_{{ .Data.Term }}"
data-oid-likes="likes_term_{{ .Data.Term }}"></script>
{{ end }}
</section>
-9
View File
@@ -26,14 +26,6 @@
{{ .Content }}
</div>
</section>
{{ $jsPage := resources.Get "js/page.js" }}
{{ $jsPage = $jsPage | resources.Minify | resources.Fingerprint (site.Params.fingerprintAlgorithm | default "sha512") }}
<script
type="text/javascript"
src="{{ $jsPage.RelPermalink }}"
integrity="{{ $jsPage.Data.Integrity }}"
data-oid="views_taxonomy_{{ .Data.Plural }}"
data-oid-likes="likes_taxonomy_{{ .Data.Plural }}"></script>
{{ end }}
{{ if site.Params.taxonomy.cardView }}
@@ -50,5 +42,4 @@
{{ end }}
</section>
{{ end }}
{{ end }}
-6
View File
@@ -69,12 +69,6 @@
});
</script>
{{ end }}
{{ $jsProcess := resources.Get "js/process.js" }}
{{ $jsProcess = $jsProcess | resources.Minify | resources.Fingerprint (.Site.Params.fingerprintAlgorithm | default "sha512") }}
<script
type="text/javascript"
src="{{ $jsProcess.RelPermalink }}"
integrity="{{ $jsProcess.Data.Integrity }}"></script>
{{/* Extend footer - eg. for extra scripts, etc. */}}
{{ if templates.Exists "partials/extend-footer.html" }}
{{ partialCached "extend-footer.html" . }}
-26
View File
@@ -200,32 +200,6 @@
{{ partial "extend-head-uncached.html" . }}
{{ end }}
{{/* Firebase */}}
{{ with $.Site.Params.firebase }}
{{ if isset $.Site.Params "firebase" }}
<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-auth.js"></script>
<script>
const firebaseConfig = {
apiKey: {{ $.Site.Params.firebase.apiKey }},
authDomain: {{ $.Site.Params.firebase.authDomain }},
projectId: {{ $.Site.Params.firebase.projectId }},
storageBucket: {{ $.Site.Params.firebase.storageBucket }},
messagingSenderId: {{ $.Site.Params.firebase.messagingSenderId }},
appId: {{ $.Site.Params.firebase.appId }},
measurementId: {{ $.Site.Params.firebase.measurementId }}
};
var app = firebase.initializeApp(firebaseConfig);
var db = firebase.firestore();
var auth = firebase.auth();
</script>
{{ end }}
{{ end }}
{{/* Advertisement */}}
{{ with .Site.Params.advertisement.adsense }}
<meta name="google-adsense-account" content="{{ . }}">
+61
View File
@@ -153,3 +153,64 @@
<script src="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous"></script>
{{ end }}
{{ end }}
{{ if site.Params.firebase.apiKey }}
{{ if in (slice "page" "section") .Kind }}
{{ $translations := .AllTranslations }}
{{ with .File }}
{{ $path := .Path }}
{{ range $translations }}
{{ $path = replace $path (print "." .Lang ".md") ".md" }}
{{ end }}
{{ partial "inline/firebase-config.html" (dict "views" (printf "views_%s" $path) "likes" (printf "likes_%s" $path)) }}
{{ end }}
{{ else if eq .Kind "term" }}
{{ partial "inline/firebase-config.html" (dict "views" (printf "views_term_%s" .Data.Term) "likes" (printf "likes_term_%s" .Data.Term)) }}
{{ else if eq .Kind "taxonomy" }}
{{ partial "inline/firebase-config.html" (dict "views" (printf "views_taxonomy_%s" .Data.Plural) "likes" (printf "likes_taxonomy_%s" .Data.Plural)) }}
{{ else if eq .Kind "home" }}
{{ partial "inline/firebase-config.html" (dict "views" (printf "views_home") "likes" (printf "likes_home")) }}
{{ end }}
<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-firestore.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-auth.js"></script>
<script>
const firebaseConfig = {
apiKey: {{ site.Params.firebase.apiKey }},
authDomain: {{ site.Params.firebase.authDomain }},
projectId: {{ site.Params.firebase.projectId }},
storageBucket: {{ site.Params.firebase.storageBucket }},
messagingSenderId: {{ site.Params.firebase.messagingSenderId }},
appId: {{ site.Params.firebase.appId }},
measurementId: {{ site.Params.firebase.measurementId }}
};
var app = firebase.initializeApp(firebaseConfig);
var db = firebase.firestore();
var auth = firebase.auth();
</script> {{/* */}}
{{ $firebase := resources.Get "js/firebase.js" }}
{{ $firebase = $firebase | resources.Minify | resources.Fingerprint (site.Params.fingerprintAlgorithm | default "sha512") }}
<script
type="text/javascript"
src="{{ $firebase.RelPermalink }}"
integrity="{{ $firebase.Data.Integrity }}"></script>
{{ end }}
{{ define "partials/inline/firebase-config.html" }}
<script id="firebase-config" type="application/json">
{
"config": {
"apiKey": "{{ site.Params.firebase.apiKey }}",
"authDomain": "{{ site.Params.firebase.authDomain }}",
"projectId": "{{ site.Params.firebase.projectId }}",
"storageBucket": "{{ site.Params.firebase.storageBucket }}",
"messagingSenderId": "{{ site.Params.firebase.messagingSenderId }}",
"appId": "{{ site.Params.firebase.appId }}",
"measurementId": "{{ site.Params.firebase.measurementId }}"
},
"oids": {{ . | jsonify | safeJS }}
}
</script>
{{ end }}