diff --git a/_config.yml b/_config.yml index 82854a02e..54b857e1e 100644 --- a/_config.yml +++ b/_config.yml @@ -50,15 +50,11 @@ google_site_verification: google_meta_tag_verification # change to your verifica # -------------------------- google_analytics: - id: '' # Fill with your Google Analytics ID + id: '' # fill in your Google Analytics ID + # Google Analytics pageviews report settings pv: - # The Google Analytics pageviews switch. - # DO NOT enable it unless you know how to deploy the Google Analytics superProxy. - 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. + proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine + cache_path: # the local PV cache data, friendly to visitors from GFW region # Prefer color scheme setting. # diff --git a/_includes/head.html b/_includes/head.html index 30e5eef85..f3b5ca3ae 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -8,17 +8,12 @@ {% if page.layout == 'home' or page.layout == 'post' %} - {% if site.google_analytics.pv.enabled %} - - {% if site.google_analytics.pv.proxy_endpoint != '' - and site.google_analytics.pv.proxy_endpoint %} - - {% endif %} - - {% if site.google_analytics.pv.cache %} - - {% endif %} + {% if site.google_analytics.pv.proxy_endpoint %} + + {% endif %} + {% if site.google_analytics.pv.cache_path %} + {% endif %} {% endif %} @@ -46,9 +41,12 @@ - {% if site.google_analytics.pv.proxy_url and site.google_analytics.pv.enabled %} - - + {% if site.google_analytics.pv.proxy_endpoint %} + {% assign proxy_url = site.google_analytics.pv.proxy_endpoint + | replace: "https://", "" | split: "/" | first | prepend: "https://" %} + + + {% endif %} {% endif %} diff --git a/_includes/js-selector.html b/_includes/js-selector.html index 6440f9df0..75a4ca852 100644 --- a/_includes/js-selector.html +++ b/_includes/js-selector.html @@ -3,7 +3,7 @@ --> {% 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 %} diff --git a/_layouts/home.html b/_layouts/home.html index 9d77caed6..9db917660 100644 --- a/_layouts/home.html +++ b/_layouts/home.html @@ -68,7 +68,7 @@ layout: page {% include read-time.html content=post.content %} - {% if site.google_analytics.pv.enabled %} + {% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %} diff --git a/_layouts/post.html b/_layouts/post.html index 3e15b6952..d95aec671 100644 --- a/_layouts/post.html +++ b/_layouts/post.html @@ -33,7 +33,7 @@ layout: default {% include read-time.html content=content %} - {% if site.google_analytics.pv.enabled %} + {% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %} {% endif %} diff --git a/_posts/2021-01-03-enable-google-pv.md b/_posts/2021-01-03-enable-google-pv.md index 30ca6e2f9..2ed5d478e 100644 --- a/_posts/2021-01-03-enable-google-pv.md +++ b/_posts/2021-01-03-enable-google-pv.md @@ -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 @@ -39,14 +39,11 @@ Now, click on the new data stream and grab the **Measurement ID**. It should loo ```yaml 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: - # The Google Analytics pageviews switch. - 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. + proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine + cache_path: # the local PV cache data, friendly to visitors from GFW region ``` 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: - ```yaml google_analytics: - id: 'G-XXXXXXXXXX' # Fill with your Google Analytics ID + id: 'G-V6XXXXXXX' # fill in your Google Analytics ID 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=' - 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. diff --git a/assets/js/_utils/pageviews.js b/assets/js/_utils/pageviews.js index dc1514d5c..fbc032802 100644 --- a/assets/js/_utils/pageviews.js +++ b/assets/js/_utils/pageviews.js @@ -18,6 +18,11 @@ const getInitStatus = (function () { }()); const PvOpts = (function () { + function hasContent(selector) { + let content = $(selector).attr("content"); + return (typeof content !== "undefined" && content !== false); + } + return { getProxyEndpoint() { return $("meta[name=pv-proxy-endpoint]").attr("content"); @@ -25,22 +30,18 @@ const PvOpts = (function () { getLocalData() { return $("meta[name=pv-cache-path]").attr("content"); }, + hasProxyEndpoint() { + return hasContent("meta[name=pv-proxy-endpoint]"); + }, hasLocalData() { - let path = PvOpts.getLocalData(); - return (typeof path !== "undefined" && path !== false); + return hasContent("meta[name=pv-cache-path]"); } } }()); -const PvData = (function () { +const PvStorage = (function () { const KEY_PV = "pv"; const KEY_CREATION = "pv_created_date"; - const KEY_PV_SRC = "pv_source"; - - const Source = { - ORIGIN: "origin", - PROXY: "proxy" - }; function get(key) { return localStorage.getItem(key); @@ -51,48 +52,30 @@ const PvData = (function () { } return { - getData() { + hasCache() { + return (localStorage.getItem(KEY_PV) !== null); + }, + getCache() { // get data from browser cache return JSON.parse(localStorage.getItem(KEY_PV)); }, - saveOriginCache(pv) { + saveCache(pv) { set(KEY_PV, pv); - set(KEY_PV_SRC, Source.ORIGIN); 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() { - if (PvData.isFromOrigin()) { - let date = new Date(get(KEY_CREATION)); - date.setDate(date.getDate() + 1); /* update origin records every day */ - 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; + let date = new Date(get(KEY_CREATION)); + date.setHours(date.getHours() + 1); // per hour + return Date.now() >= date.getTime(); }, getAllPageviews() { - return PvData.getData().totalsForAllResults["ga:pageviews"]; + return PvStorage.getCache().totalsForAllResults["ga:pageviews"]; }, newerThan(pv) { - return PvData.getAllPageviews() > pv.totalsForAllResults["ga:pageviews"]; + return PvStorage.getAllPageviews() > pv.totalsForAllResults["ga:pageviews"]; }, inspectKeys() { if (localStorage.getItem(KEY_PV) === null - || localStorage.getItem(KEY_PV_SRC) === null || localStorage.getItem(KEY_CREATION) === null) { localStorage.clear(); } @@ -101,7 +84,6 @@ const PvData = (function () { }()); /* PvData */ - function countUp(min, max, destId) { if (min < max) { let numAnim = new CountUp(destId, min, max); @@ -113,7 +95,6 @@ function countUp(min, max, destId) { } } - function countPV(path, rows) { let count = 0; @@ -130,7 +111,6 @@ function countPV(path, rows) { return count; } - function tacklePV(rows, path, elem, hasInit) { let count = countPV(path, rows); count = (count === 0 ? 1 : count); @@ -145,7 +125,6 @@ function tacklePV(rows, path, elem, hasInit) { } } - function displayPageviews(data) { if (typeof data === "undefined") { return; @@ -166,37 +145,38 @@ function displayPageviews(data) { } } - function fetchProxyPageviews() { - $.ajax({ - type: "GET", - url: PvOpts.getProxyEndpoint(), - dataType: "jsonp", - jsonpCallback: "displayPageviews", - success: (data, textStatus, jqXHR) => { - PvData.saveProxyCache(JSON.stringify(data)); - }, - error: (jqXHR, textStatus, errorThrown) => { - console.log("Failed to load pageviews from proxy server: " + errorThrown); - } - }); + if (PvOpts.hasProxyEndpoint()) { + $.ajax({ + type: "GET", + url: PvOpts.getProxyEndpoint(), + dataType: "jsonp", + jsonpCallback: "displayPageviews", + success: (data, textStatus, jqXHR) => { + PvStorage.saveCache(JSON.stringify(data)); + }, + error: (jqXHR, textStatus, errorThrown) => { + console.log("Failed to load pageviews from proxy server: " + errorThrown); + } + }); + } } - -function fetchPageviews(fetchOrigin = true, coverOrigin = false) { - if (fetchOrigin) { +function loadPageviews(hasCache = false) { + if (PvOpts.hasLocalData()) { fetch(PvOpts.getLocalData()) .then((response) => response.json()) .then((data) => { - if (coverOrigin) { - if (PvData.newerThan(data)) { - return; - } + // The cache from the proxy will sometimes be more recent than the local one + if (hasCache && PvStorage.newerThan(data)) { + return; } displayPageviews(data); - PvData.saveOriginCache(JSON.stringify(data)); + PvStorage.saveCache(JSON.stringify(data)); }) - .then(() => fetchProxyPageviews()); + .then(() => { + fetchProxyPageviews(); + }); } else { fetchProxyPageviews(); @@ -204,31 +184,20 @@ function fetchPageviews(fetchOrigin = true, coverOrigin = false) { } - $(function() { if ($(".pageviews").length <= 0) { return; } - PvData.inspectKeys(); - let data = PvData.getData(); - - if (data) { - displayPageviews(data); - - if (PvData.isExpired()) { - fetchPageviews(true, PvData.isFromProxy()); - - } else { - - if (PvData.isFromOrigin()) { - fetchPageviews(false); - } + PvStorage.inspectKeys(); + if (PvStorage.hasCache()) { + displayPageviews(PvStorage.getCache()); + if (!PvStorage.isExpired()) { + return; } - - } else { - fetchPageviews(PvOpts.hasLocalData()); } + loadPageviews(PvStorage.hasCache()); + }); diff --git a/assets/js/data/cache-list.js b/assets/js/data/cache-list.js index 32b4c8448..86a939aa3 100644 --- a/assets/js/data/cache-list.js +++ b/assets/js/data/cache-list.js @@ -53,9 +53,9 @@ const include = [ ]; const exclude = [ - {%- if site.google_analytics.pv.proxy_url and site.google_analytics.pv.enabled -%} - '{{ site.google_analytics.pv.proxy_url }}', + {%- if site.google_analytics.pv.proxy_endpoint -%} + 'https://{{ site.google_analytics.pv.proxy_endpoint | replace: "https://", "" | split: "/" | first }}', {%- endif -%} - '/assets/js/data/pageviews.json', - '/img.shields.io/' + 'https://img.shields.io', + '/assets/js/data/pageviews.json' ]; diff --git a/assets/js/dist/pvreport.min.js b/assets/js/dist/pvreport.min.js index c2c6f73ec..c06ba190f 100644 --- a/assets/js/dist/pvreport.min.js +++ b/assets/js/dist/pvreport.min.js @@ -3,4 +3,4 @@ * © 2019 Cotes Chung * 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(er&&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()))}); \ No newline at end of file +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(tn&&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()))}); \ No newline at end of file