Simplify the PV config options

- Remove options `site.google_analytics.pv.enabled` and `site.google_analytics.pv.proxy_url`
- Rename options `site.google_analytics.pv.cache` to `site.google_analytics.pv.cache_path`
This commit is contained in:
Cotes Chung 2021-04-06 14:05:55 +08:00
parent 48e4c7e6d3
commit 4a0242e496
9 changed files with 80 additions and 125 deletions

View file

@ -50,15 +50,11 @@ google_site_verification: google_meta_tag_verification # change to your verifica
# -------------------------- # --------------------------
google_analytics: google_analytics:
id: '' # Fill with your Google Analytics ID id: '' # fill in your Google Analytics ID
# Google Analytics pageviews report settings
pv: pv:
# The Google Analytics pageviews switch. proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine
# DO NOT enable it unless you know how to deploy the Google Analytics superProxy. cache_path: # the local PV cache data, friendly to visitors from GFW region
enabled: false
# the next options only valid when `google_analytics.pv` is enabled.
proxy_url: ''
proxy_endpoint: ''
cache: false # pv data local cache, good for the users from GFW area.
# Prefer color scheme setting. # Prefer color scheme setting.
# #

View file

@ -8,17 +8,12 @@
{% if page.layout == 'home' or page.layout == 'post' %} {% if page.layout == 'home' or page.layout == 'post' %}
{% if site.google_analytics.pv.enabled %} {% if site.google_analytics.pv.proxy_endpoint %}
{% if site.google_analytics.pv.proxy_endpoint != ''
and site.google_analytics.pv.proxy_endpoint %}
<meta name="pv-proxy-endpoint" content="{{ site.google_analytics.pv.proxy_endpoint }}"> <meta name="pv-proxy-endpoint" content="{{ site.google_analytics.pv.proxy_endpoint }}">
{% endif %} {% endif %}
{% if site.google_analytics.pv.cache %} {% if site.google_analytics.pv.cache_path %}
<meta name="pv-cache-path" content="{{ '/assets/js/data/pageviews.json' | relative_url }}"> <meta name="pv-cache-path" content="{{ site.google_analytics.pv.cache_path | relative_url }}">
{% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}
@ -46,9 +41,12 @@
<link rel="preconnect" href="https://www.googletagmanager.com" crossorigin="anonymous"> <link rel="preconnect" href="https://www.googletagmanager.com" crossorigin="anonymous">
<link rel="dns-prefetch" href="https://www.googletagmanager.com"> <link rel="dns-prefetch" href="https://www.googletagmanager.com">
{% if site.google_analytics.pv.proxy_url and site.google_analytics.pv.enabled %} {% if site.google_analytics.pv.proxy_endpoint %}
<link rel="preconnect" href="{{ site.google_analytics.pv.proxy_url }}" crossorigin="use-credentials"> {% assign proxy_url = site.google_analytics.pv.proxy_endpoint
<link rel="dns-prefetch" href="{{ site.google_analytics.pv.proxy_url }}"> | replace: "https://", "" | split: "/" | first | prepend: "https://" %}
<link rel="preconnect" href="{{ proxy_url }}" crossorigin="use-credentials">
<link rel="dns-prefetch" href="{{ proxy_url }}">
{% endif %} {% endif %}
{% endif %} {% endif %}

View file

@ -3,7 +3,7 @@
--> -->
{% if page.layout == 'home' or page.layout == 'post' %} {% if page.layout == 'home' or page.layout == 'post' %}
{% if site.google_analytics.pv.enabled %} {% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
<!-- pv-report needs countup.js --> <!-- pv-report needs countup.js -->
<script async src="https://cdn.jsdelivr.net/npm/countup.js@1.9.3/dist/countUp.min.js"></script> <script async src="https://cdn.jsdelivr.net/npm/countup.js@1.9.3/dist/countUp.min.js"></script>
<script async src="{{ '/assets/js/dist/pvreport.min.js' | relative_url }}"></script> <script async src="{{ '/assets/js/dist/pvreport.min.js' | relative_url }}"></script>

View file

@ -68,7 +68,7 @@ layout: page
{% include read-time.html content=post.content %} {% include read-time.html content=post.content %}
<!-- page views --> <!-- page views -->
{% if site.google_analytics.pv.enabled %} {% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
<i class="far fa-eye fa-fw"></i> <i class="far fa-eye fa-fw"></i>
<span id="pv_{{-post.title-}}" class="pageviews"> <span id="pv_{{-post.title-}}" class="pageviews">
<i class="fas fa-spinner fa-spin fa-fw"></i> <i class="fas fa-spinner fa-spin fa-fw"></i>

View file

@ -33,7 +33,7 @@ layout: default
{% include read-time.html content=content %} {% include read-time.html content=content %}
<!-- page views --> <!-- page views -->
{% if site.google_analytics.pv.enabled %} {% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %}
<span id="pv" class="pageviews"><i class="fas fa-spinner fa-spin fa-fw"></i></span> <span id="pv" class="pageviews"><i class="fas fa-spinner fa-spin fa-fw"></i></span>
{% endif %} {% endif %}

View file

@ -7,7 +7,7 @@ tags: [google analytics, pageviews]
--- ---
This post is to enable Page Views on the [**Chirpy**][chirpy-homepage] theme based blog that you just built. This requires technical knowledge and it's recommended to keep the `google_analytics.pv` disabled unless you have a good reason. If your website has low traffic, the page views count would discourage you to write more blogs. With that said, let's start with the setup. This post is to enable Page Views on the [**Chirpy**][chirpy-homepage] theme based blog that you just built. This requires technical knowledge and it's recommended to keep the `google_analytics.pv.*` empty unless you have a good reason. If your website has low traffic, the page views count would discourage you to write more blogs. With that said, let's start with the setup.
## Set up Google Analytics ## Set up Google Analytics
@ -39,14 +39,11 @@ Now, click on the new data stream and grab the **Measurement ID**. It should loo
```yaml ```yaml
google_analytics: google_analytics:
id: 'G-V6XXXXXXX' # Fill with your Google Analytics ID id: 'G-V6XXXXXXX' # fill in your Google Analytics ID
# Google Analytics pageviews report settings
pv: pv:
# The Google Analytics pageviews switch. proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine
enabled: false cache_path: # the local PV cache data, friendly to visitors from GFW region
# the next options only valid when `google_analytics.pv` is enabled.
proxy_url: ''
proxy_endpoint: ''
cache: false # pv data local cache, good for the users from GFW area.
``` ```
When you push these changes to your blog, you should start seeing the traffic on your Google Analytics. Play around with Google Analytics dashboard to get familiar with the options available as it takes like 5 mins to pickup your changes. You should now be able to monitor your traffic in realtime. When you push these changes to your blog, you should start seeing the traffic on your Google Analytics. Play around with Google Analytics dashboard to get familiar with the options available as it takes like 5 mins to pickup your changes. You should now be able to monitor your traffic in realtime.
@ -222,17 +219,12 @@ Once all the hard part is done, it is very easy to enable the Page View on Chirp
Update the `_config.yml` file of [**Chirpy**][chirpy-homepage] project with the values from your dashboard, to look similar to the following: Update the `_config.yml` file of [**Chirpy**][chirpy-homepage] project with the values from your dashboard, to look similar to the following:
```yaml ```yaml
google_analytics: google_analytics:
id: 'G-XXXXXXXXXX' # Fill with your Google Analytics ID id: 'G-V6XXXXXXX' # fill in your Google Analytics ID
pv: pv:
# The Google Analytics pageviews switch.
enabled: true
# the next options only valid when `google_analytics.pv` is enabled.
proxy_url: 'https://PROJECT_ID.REGION_ID.r.appspot.com'
proxy_endpoint: 'https://PROJECT_ID.REGION_ID.r.appspot.com/query?id=<ID FROM SUPER PROXY>' proxy_endpoint: 'https://PROJECT_ID.REGION_ID.r.appspot.com/query?id=<ID FROM SUPER PROXY>'
cache: false # pv data local cache, good for the users from GFW area. cache_path: # the local PV cache data, friendly to visitors from GFW region
``` ```
Now, you should see the Page View enabled on your blog. Now, you should see the Page View enabled on your blog.

View file

@ -18,6 +18,11 @@ const getInitStatus = (function () {
}()); }());
const PvOpts = (function () { const PvOpts = (function () {
function hasContent(selector) {
let content = $(selector).attr("content");
return (typeof content !== "undefined" && content !== false);
}
return { return {
getProxyEndpoint() { getProxyEndpoint() {
return $("meta[name=pv-proxy-endpoint]").attr("content"); return $("meta[name=pv-proxy-endpoint]").attr("content");
@ -25,22 +30,18 @@ const PvOpts = (function () {
getLocalData() { getLocalData() {
return $("meta[name=pv-cache-path]").attr("content"); return $("meta[name=pv-cache-path]").attr("content");
}, },
hasProxyEndpoint() {
return hasContent("meta[name=pv-proxy-endpoint]");
},
hasLocalData() { hasLocalData() {
let path = PvOpts.getLocalData(); return hasContent("meta[name=pv-cache-path]");
return (typeof path !== "undefined" && path !== false);
} }
} }
}()); }());
const PvData = (function () { const PvStorage = (function () {
const KEY_PV = "pv"; const KEY_PV = "pv";
const KEY_CREATION = "pv_created_date"; const KEY_CREATION = "pv_created_date";
const KEY_PV_SRC = "pv_source";
const Source = {
ORIGIN: "origin",
PROXY: "proxy"
};
function get(key) { function get(key) {
return localStorage.getItem(key); return localStorage.getItem(key);
@ -51,48 +52,30 @@ const PvData = (function () {
} }
return { return {
getData() { hasCache() {
return (localStorage.getItem(KEY_PV) !== null);
},
getCache() {
// get data from browser cache // get data from browser cache
return JSON.parse(localStorage.getItem(KEY_PV)); return JSON.parse(localStorage.getItem(KEY_PV));
}, },
saveOriginCache(pv) { saveCache(pv) {
set(KEY_PV, pv); set(KEY_PV, pv);
set(KEY_PV_SRC, Source.ORIGIN);
set(KEY_CREATION, new Date().toJSON()); set(KEY_CREATION, new Date().toJSON());
}, },
saveProxyCache(pv) {
set(KEY_PV, pv);
set(KEY_PV_SRC, Source.PROXY);
set(KEY_CREATION, new Date().toJSON());
},
isFromOrigin() {
return get(KEY_PV_SRC) === Source.ORIGIN;
},
isFromProxy() {
return get(KEY_PV_SRC) === Source.PROXY;
},
isExpired() { isExpired() {
if (PvData.isFromOrigin()) {
let date = new Date(get(KEY_CREATION)); let date = new Date(get(KEY_CREATION));
date.setDate(date.getDate() + 1); /* update origin records every day */ date.setHours(date.getHours() + 1); // per hour
return Date.now() >= date.getTime(); return Date.now() >= date.getTime();
} else if (PvData.isFromProxy()) {
let date = new Date(get(KEY_CREATION));
date.setHours(date.getHours() + 1); /* update proxy records per hour */
return Date.now() >= date.getTime();
}
return false;
}, },
getAllPageviews() { getAllPageviews() {
return PvData.getData().totalsForAllResults["ga:pageviews"]; return PvStorage.getCache().totalsForAllResults["ga:pageviews"];
}, },
newerThan(pv) { newerThan(pv) {
return PvData.getAllPageviews() > pv.totalsForAllResults["ga:pageviews"]; return PvStorage.getAllPageviews() > pv.totalsForAllResults["ga:pageviews"];
}, },
inspectKeys() { inspectKeys() {
if (localStorage.getItem(KEY_PV) === null if (localStorage.getItem(KEY_PV) === null
|| localStorage.getItem(KEY_PV_SRC) === null
|| localStorage.getItem(KEY_CREATION) === null) { || localStorage.getItem(KEY_CREATION) === null) {
localStorage.clear(); localStorage.clear();
} }
@ -101,7 +84,6 @@ const PvData = (function () {
}()); /* PvData */ }()); /* PvData */
function countUp(min, max, destId) { function countUp(min, max, destId) {
if (min < max) { if (min < max) {
let numAnim = new CountUp(destId, min, max); let numAnim = new CountUp(destId, min, max);
@ -113,7 +95,6 @@ function countUp(min, max, destId) {
} }
} }
function countPV(path, rows) { function countPV(path, rows) {
let count = 0; let count = 0;
@ -130,7 +111,6 @@ function countPV(path, rows) {
return count; return count;
} }
function tacklePV(rows, path, elem, hasInit) { function tacklePV(rows, path, elem, hasInit) {
let count = countPV(path, rows); let count = countPV(path, rows);
count = (count === 0 ? 1 : count); count = (count === 0 ? 1 : count);
@ -145,7 +125,6 @@ function tacklePV(rows, path, elem, hasInit) {
} }
} }
function displayPageviews(data) { function displayPageviews(data) {
if (typeof data === "undefined") { if (typeof data === "undefined") {
return; return;
@ -166,37 +145,38 @@ function displayPageviews(data) {
} }
} }
function fetchProxyPageviews() { function fetchProxyPageviews() {
if (PvOpts.hasProxyEndpoint()) {
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: PvOpts.getProxyEndpoint(), url: PvOpts.getProxyEndpoint(),
dataType: "jsonp", dataType: "jsonp",
jsonpCallback: "displayPageviews", jsonpCallback: "displayPageviews",
success: (data, textStatus, jqXHR) => { success: (data, textStatus, jqXHR) => {
PvData.saveProxyCache(JSON.stringify(data)); PvStorage.saveCache(JSON.stringify(data));
}, },
error: (jqXHR, textStatus, errorThrown) => { error: (jqXHR, textStatus, errorThrown) => {
console.log("Failed to load pageviews from proxy server: " + errorThrown); console.log("Failed to load pageviews from proxy server: " + errorThrown);
} }
}); });
}
} }
function loadPageviews(hasCache = false) {
function fetchPageviews(fetchOrigin = true, coverOrigin = false) { if (PvOpts.hasLocalData()) {
if (fetchOrigin) {
fetch(PvOpts.getLocalData()) fetch(PvOpts.getLocalData())
.then((response) => response.json()) .then((response) => response.json())
.then((data) => { .then((data) => {
if (coverOrigin) { // The cache from the proxy will sometimes be more recent than the local one
if (PvData.newerThan(data)) { if (hasCache && PvStorage.newerThan(data)) {
return; return;
} }
}
displayPageviews(data); displayPageviews(data);
PvData.saveOriginCache(JSON.stringify(data)); PvStorage.saveCache(JSON.stringify(data));
}) })
.then(() => fetchProxyPageviews()); .then(() => {
fetchProxyPageviews();
});
} else { } else {
fetchProxyPageviews(); fetchProxyPageviews();
@ -204,31 +184,20 @@ function fetchPageviews(fetchOrigin = true, coverOrigin = false) {
} }
$(function() { $(function() {
if ($(".pageviews").length <= 0) { if ($(".pageviews").length <= 0) {
return; return;
} }
PvData.inspectKeys(); PvStorage.inspectKeys();
let data = PvData.getData();
if (data) { if (PvStorage.hasCache()) {
displayPageviews(data); displayPageviews(PvStorage.getCache());
if (!PvStorage.isExpired()) {
if (PvData.isExpired()) { return;
fetchPageviews(true, PvData.isFromProxy()); }
} else {
if (PvData.isFromOrigin()) {
fetchPageviews(false);
} }
} loadPageviews(PvStorage.hasCache());
} else {
fetchPageviews(PvOpts.hasLocalData());
}
}); });

View file

@ -53,9 +53,9 @@ const include = [
]; ];
const exclude = [ const exclude = [
{%- if site.google_analytics.pv.proxy_url and site.google_analytics.pv.enabled -%} {%- if site.google_analytics.pv.proxy_endpoint -%}
'{{ site.google_analytics.pv.proxy_url }}', 'https://{{ site.google_analytics.pv.proxy_endpoint | replace: "https://", "" | split: "/" | first }}',
{%- endif -%} {%- endif -%}
'/assets/js/data/pageviews.json', 'https://img.shields.io',
'/img.shields.io/' '/assets/js/data/pageviews.json'
]; ];

View file

@ -3,4 +3,4 @@
* © 2019 Cotes Chung * © 2019 Cotes Chung
* MIT Licensed * MIT Licensed
*/ */
const getInitStatus=function(){let e=!1;return()=>{var t=e;return e=e||!0,t}}(),PvOpts={getProxyEndpoint(){return $("meta[name=pv-proxy-endpoint]").attr("content")},getLocalData(){return $("meta[name=pv-cache-path]").attr("content")},hasLocalData(){var t=PvOpts.getLocalData();return void 0!==t&&!1!==t}},PvData=function(){const e="pv",a="pv_created_date",r="pv_source",n={ORIGIN:"origin",PROXY:"proxy"};function o(t){return localStorage.getItem(t)}function i(t,e){localStorage.setItem(t,e)}return{getData(){return JSON.parse(localStorage.getItem(e))},saveOriginCache(t){i(e,t),i(r,n.ORIGIN),i(a,(new Date).toJSON())},saveProxyCache(t){i(e,t),i(r,n.PROXY),i(a,(new Date).toJSON())},isFromOrigin(){return o(r)===n.ORIGIN},isFromProxy(){return o(r)===n.PROXY},isExpired(){if(PvData.isFromOrigin()){let t=new Date(o(a));return t.setDate(t.getDate()+1),Date.now()>=t.getTime()}if(PvData.isFromProxy()){let t=new Date(o(a));return t.setHours(t.getHours()+1),Date.now()>=t.getTime()}return!1},getAllPageviews(){return PvData.getData().totalsForAllResults["ga:pageviews"]},newerThan(t){return PvData.getAllPageviews()>t.totalsForAllResults["ga:pageviews"]},inspectKeys(){null!==localStorage.getItem(e)&&null!==localStorage.getItem(r)&&null!==localStorage.getItem(a)||localStorage.clear()}}}();function countUp(e,a,r){if(e<a){let t=new CountUp(r,e,a);t.error?console.error(t.error):t.start()}}function countPV(e,a){let r=0;if(void 0!==a)for(let t=0;t<a.length;++t)if(a[parseInt(t,10)][0]===e){r+=parseInt(a[parseInt(t,10)][1],10);break}return r}function tacklePV(t,e,a,r){let n=countPV(e,t);n=0===n?1:n,r?(r=parseInt(a.text().replace(/,/g,""),10),n>r&&countUp(r,n,a.attr("id"))):a.text((new Intl.NumberFormat).format(n))}function displayPageviews(t){if(void 0!==t){let e=getInitStatus();const a=t.rows;0<$("#post-list").length?$(".post-preview").each(function(){var t=$(this).find("a").attr("href");tacklePV(a,t,$(this).find(".pageviews"),e)}):0<$(".post").length&&(t=window.location.pathname,tacklePV(a,t,$("#pv"),e))}}function fetchProxyPageviews(){$.ajax({type:"GET",url:PvOpts.getProxyEndpoint(),dataType:"jsonp",jsonpCallback:"displayPageviews",success:(t,e,a)=>{PvData.saveProxyCache(JSON.stringify(t))},error:(t,e,a)=>{console.log("Failed to load pageviews from proxy server: "+a)}})}function fetchPageviews(t=!0,e=!1){t?fetch(PvOpts.getLocalData()).then(t=>t.json()).then(t=>{e&&PvData.newerThan(t)||(displayPageviews(t),PvData.saveOriginCache(JSON.stringify(t)))}).then(()=>fetchProxyPageviews()):fetchProxyPageviews()}$(function(){var t;$(".pageviews").length<=0||(PvData.inspectKeys(),(t=PvData.getData())?(displayPageviews(t),PvData.isExpired()?fetchPageviews(!0,PvData.isFromProxy()):PvData.isFromOrigin()&&fetchPageviews(!1)):fetchPageviews(PvOpts.hasLocalData()))}); const getInitStatus=function(){let t=!1;return()=>{var e=t;return t=t||!0,e}}(),PvOpts=function(){function e(e){e=$(e).attr("content");return void 0!==e&&!1!==e}return{getProxyEndpoint(){return $("meta[name=pv-proxy-endpoint]").attr("content")},getLocalData(){return $("meta[name=pv-cache-path]").attr("content")},hasProxyEndpoint(){return e("meta[name=pv-proxy-endpoint]")},hasLocalData(){return e("meta[name=pv-cache-path]")}}}(),PvStorage=function(){const t="pv",a="pv_created_date";function n(e,t){localStorage.setItem(e,t)}return{hasCache(){return null!==localStorage.getItem(t)},getCache(){return JSON.parse(localStorage.getItem(t))},saveCache(e){n(t,e),n(a,(new Date).toJSON())},isExpired(){let e=new Date((t=a,localStorage.getItem(t)));var t;return e.setHours(e.getHours()+1),Date.now()>=e.getTime()},getAllPageviews(){return PvStorage.getCache().totalsForAllResults["ga:pageviews"]},newerThan(e){return PvStorage.getAllPageviews()>e.totalsForAllResults["ga:pageviews"]},inspectKeys(){null!==localStorage.getItem(t)&&null!==localStorage.getItem(a)||localStorage.clear()}}}();function countUp(t,a,n){if(t<a){let e=new CountUp(n,t,a);e.error?console.error(e.error):e.start()}}function countPV(t,a){let n=0;if(void 0!==a)for(let e=0;e<a.length;++e)if(a[parseInt(e,10)][0]===t){n+=parseInt(a[parseInt(e,10)][1],10);break}return n}function tacklePV(e,t,a,n){let r=countPV(t,e);r=0===r?1:r,n?(n=parseInt(a.text().replace(/,/g,""),10),r>n&&countUp(n,r,a.attr("id"))):a.text((new Intl.NumberFormat).format(r))}function displayPageviews(e){if(void 0!==e){let t=getInitStatus();const a=e.rows;0<$("#post-list").length?$(".post-preview").each(function(){var e=$(this).find("a").attr("href");tacklePV(a,e,$(this).find(".pageviews"),t)}):0<$(".post").length&&(e=window.location.pathname,tacklePV(a,e,$("#pv"),t))}}function fetchProxyPageviews(){PvOpts.hasProxyEndpoint()&&$.ajax({type:"GET",url:PvOpts.getProxyEndpoint(),dataType:"jsonp",jsonpCallback:"displayPageviews",success:(e,t,a)=>{PvStorage.saveCache(JSON.stringify(e))},error:(e,t,a)=>{console.log("Failed to load pageviews from proxy server: "+a)}})}function loadPageviews(t=!1){PvOpts.hasLocalData()?fetch(PvOpts.getLocalData()).then(e=>e.json()).then(e=>{t&&PvStorage.newerThan(e)||(displayPageviews(e),PvStorage.saveCache(JSON.stringify(e)))}).then(()=>{fetchProxyPageviews()}):fetchProxyPageviews()}$(function(){$(".pageviews").length<=0||(PvStorage.inspectKeys(),PvStorage.hasCache()&&(displayPageviews(PvStorage.getCache()),!PvStorage.isExpired())||loadPageviews(PvStorage.hasCache()))});