Improved the PV fetching experience.
This commit is contained in:
parent
9f6173231b
commit
1ce1455ce2
9 changed files with 155 additions and 38 deletions
12
_config.yml
12
_config.yml
|
@ -55,12 +55,14 @@ google_analytics:
|
||||||
# Fill with your Google Analytics ID
|
# Fill with your Google Analytics ID
|
||||||
id: ''
|
id: ''
|
||||||
# The Google Analytics pageviews switch.
|
# The Google Analytics pageviews switch.
|
||||||
# DO NOT enable it unless you know how to deploy the Google Analytics superProxy.
|
|
||||||
pv: false
|
|
||||||
# superProxy baseURL and URL, only valid when `google_analytics.pv` is set to 'true'
|
|
||||||
proxy_baseurl: ''
|
|
||||||
proxy_url: ''
|
|
||||||
|
|
||||||
|
pv:
|
||||||
|
# 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.
|
||||||
|
|
||||||
disqus:
|
disqus:
|
||||||
comments: false # boolean type, the global switch for posts comments.
|
comments: false # boolean type, the global switch for posts comments.
|
||||||
|
|
|
@ -34,9 +34,9 @@
|
||||||
<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.proxy_baseurl and site.google_analytics.pv %}
|
{% if site.google_analytics.pv.proxy_url and site.google_analytics.pv.enabled %}
|
||||||
<link rel="preconnect" href="{{ site.google_analytics.proxy_baseurl }}" crossorigin="use-credentials">
|
<link rel="preconnect" href="{{ site.google_analytics.pv.proxy_url }}" crossorigin="use-credentials">
|
||||||
<link rel="dns-prefetch" href="{{ site.google_analytics.proxy_baseurl }}">
|
<link rel="dns-prefetch" href="{{ site.google_analytics.pv.proxy_url }}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
@ -122,7 +122,8 @@
|
||||||
|
|
||||||
{% if page.layout == 'home' or page.layout == 'post' %}
|
{% if page.layout == 'home' or page.layout == 'post' %}
|
||||||
<script src="{{ site.baseurl }}/assets/js/dist/timeago.min.js" async></script>
|
<script src="{{ site.baseurl }}/assets/js/dist/timeago.min.js" async></script>
|
||||||
{% if site.google_analytics.pv %}
|
{% if site.google_analytics.pv.enabled %}
|
||||||
|
<script src="{{ site.baseurl }}/assets/data/pv-data.json"></script>
|
||||||
<script src="{{ site.baseurl }}/assets/lib/countUp.min.js" async></script>
|
<script src="{{ site.baseurl }}/assets/lib/countUp.min.js" async></script>
|
||||||
<script src="{{ site.baseurl }}/assets/js/dist/pageviews.min.js" async></script>
|
<script src="{{ site.baseurl }}/assets/js/dist/pageviews.min.js" async></script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -28,7 +28,7 @@ layout: page
|
||||||
<i class="unloaded">{{ post.date | date_to_xmlschema }}</i>
|
<i class="unloaded">{{ post.date | date_to_xmlschema }}</i>
|
||||||
</span>
|
</span>
|
||||||
<!-- page views -->
|
<!-- page views -->
|
||||||
{% if site.google_analytics.pv %}
|
{% if site.google_analytics.pv.enabled %}
|
||||||
<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>
|
||||||
|
|
|
@ -31,7 +31,7 @@ layout: default
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- page views -->
|
<!-- page views -->
|
||||||
{% if site.google_analytics.pv %}
|
{% if site.google_analytics.pv.enabled %}
|
||||||
<div>
|
<div>
|
||||||
<span id="pv" class="pageviews"><i class="fas fa-spinner fa-spin fa-fw"></i></span> views
|
<span id="pv" class="pageviews"><i class="fas fa-spinner fa-spin fa-fw"></i></span> views
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
---
|
|
||||||
---
|
|
||||||
|
|
||||||
{
|
|
||||||
"proxyUrl": "{{ site.google_analytics.proxy_url }}"
|
|
||||||
}
|
|
13
assets/data/pv-data.json
Normal file
13
assets/data/pv-data.json
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
---
|
||||||
|
layout: compress
|
||||||
|
---
|
||||||
|
|
||||||
|
const proxyData = '{"url": "{{ site.google_analytics.pv.proxy_endpoint }}"}';
|
||||||
|
|
||||||
|
{%- capture pv_data -%}
|
||||||
|
{%- if site.google_analytics.pv.cache and site.google_analytics.pv.enabled -%}
|
||||||
|
{% include_relative pageviews.json %}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endcapture -%}
|
||||||
|
|
||||||
|
const pageviews = '{{ pv_data }}';
|
|
@ -1,4 +1,5 @@
|
||||||
---
|
---
|
||||||
|
layout: compress
|
||||||
---
|
---
|
||||||
|
|
||||||
[
|
[
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*
|
*
|
||||||
* Dependences:
|
* Dependences:
|
||||||
* - jQuery
|
* - jQuery
|
||||||
* - countUp.js(https://github.com/inorganik/countUp.js)
|
* - countUp.js <https://github.com/inorganik/countUp.js>
|
||||||
*
|
*
|
||||||
* v2.0
|
* v2.0
|
||||||
* https://github.com/cotes2020/jekyll-theme-chirpy
|
* https://github.com/cotes2020/jekyll-theme-chirpy
|
||||||
|
@ -77,42 +77,148 @@ function displayPageviews(data) {
|
||||||
var path = window.location.pathname;
|
var path = window.location.pathname;
|
||||||
tacklePV(rows, path, $('#pv'), hasInit);
|
tacklePV(rows, path, $('#pv'), hasInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var getInitStatus = (function() {
|
var getInitStatus = (function() {
|
||||||
var hasInit = false;
|
var hasInit = false;
|
||||||
return function() {
|
return function() {
|
||||||
if (hasInit) {
|
let ret = hasInit;
|
||||||
return true;
|
if (!hasInit) {
|
||||||
} else {
|
|
||||||
hasInit = true;
|
hasInit = true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
var PvCache = (function() {
|
||||||
|
const KEY_PV = "pv";
|
||||||
|
const KEY_CREATION = "pv-created-date";
|
||||||
|
const KEY_PV_TYPE = "pv-type";
|
||||||
|
|
||||||
|
var PvType = {
|
||||||
|
ORIGIN: "origin",
|
||||||
|
PROXY: "proxy"
|
||||||
|
};
|
||||||
|
|
||||||
|
function get(key) {
|
||||||
|
return localStorage.getItem(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
function set(key, val) {
|
||||||
|
localStorage.setItem(key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
getData: function() {
|
||||||
|
return JSON.parse(localStorage.getItem(KEY_PV) );
|
||||||
|
},
|
||||||
|
saveOriginCache: function(pv) {
|
||||||
|
set(KEY_PV, pv);
|
||||||
|
set(KEY_PV_TYPE, PvType.ORIGIN );
|
||||||
|
set(KEY_CREATION, new Date().toJSON() );
|
||||||
|
},
|
||||||
|
saveProxyCache: function(pv) {
|
||||||
|
set(KEY_PV, pv);
|
||||||
|
set(KEY_PV_TYPE, PvType.PROXY );
|
||||||
|
set(KEY_CREATION, new Date().toJSON() );
|
||||||
|
},
|
||||||
|
isOriginCache: function() {
|
||||||
|
return get(KEY_PV_TYPE) == PvType.ORIGIN;
|
||||||
|
},
|
||||||
|
isProxyCache: function() {
|
||||||
|
return get(KEY_PV_TYPE) == PvType.PROXY;
|
||||||
|
},
|
||||||
|
isExpired: function() {
|
||||||
|
if (PvCache.isOriginCache() ) {
|
||||||
|
let date = new Date(get(KEY_CREATION));
|
||||||
|
date.setDate(date.getDate() + 1); // fetch origin-data every day
|
||||||
|
return Date.now() >= date.getTime();
|
||||||
|
|
||||||
|
} else if (PvCache.isProxyCache() ) {
|
||||||
|
let date = new Date(get(KEY_CREATION) );
|
||||||
|
date.setHours(date.getHours() + 1); // proxy-data is updated every hour
|
||||||
|
return Date.now() >= date.getTime();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
getAllPagevies: function() {
|
||||||
|
return PvCache.getData().totalsForAllResults["ga:pageviews"];
|
||||||
|
},
|
||||||
|
newerThan: function(pv) {
|
||||||
|
return PvCache.getAllPagevies() > pv.totalsForAllResults["ga:pageviews"];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})(); // PvCache
|
||||||
|
|
||||||
|
|
||||||
|
function fetchOriginPageviews(pvData) {
|
||||||
|
if (pvData === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
displayPageviews(pvData);
|
||||||
|
PvCache.saveOriginCache(JSON.stringify(pvData));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function fetchProxyPageviews() {
|
||||||
|
let proxy = JSON.parse(proxyData); // see file '/assets/data/pv-data.json'
|
||||||
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: proxy.url,
|
||||||
|
dataType: 'jsonp',
|
||||||
|
jsonpCallback: "displayPageviews",
|
||||||
|
success: function(data, textStatus, jqXHR) {
|
||||||
|
PvCache.saveProxyCache(JSON.stringify(data));
|
||||||
|
},
|
||||||
|
error: function(jqXHR, textStatus, errorThrown) {
|
||||||
|
console.log("Failed to load pageviews from proxy server: " + errorThrown);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
// load pageview if this page has .pageviews
|
|
||||||
if ($('.pageviews').length > 0) {
|
if ($('.pageviews').length > 0) {
|
||||||
|
|
||||||
// Get data from daily cache.
|
let originPvData = pageviews ? JSON.parse(pageviews) : undefined;
|
||||||
$.getJSON('/assets/data/pageviews.json', displayPageviews);
|
let cache = PvCache.getData();
|
||||||
|
|
||||||
$.getJSON('/assets/data/proxy.json', function(meta) {
|
if (cache) {
|
||||||
$.ajax({
|
if (PvCache.isExpired()) {
|
||||||
type: 'GET',
|
if (PvCache.isProxyCache() ) {
|
||||||
url: meta.proxyUrl,
|
if (originPvData) {
|
||||||
dataType: 'jsonp',
|
if (PvCache.newerThan(originPvData)) {
|
||||||
jsonpCallback: "displayPageviews",
|
displayPageviews(cache);
|
||||||
error: function(jqXHR, textStatus, errorThrown) {
|
} else {
|
||||||
console.log("Failed to load pageviews from proxy server: " + errorThrown);
|
fetchOriginPageviews(originPvData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchProxyPageviews();
|
||||||
|
|
||||||
|
} else if (PvCache.isOriginCache() ) {
|
||||||
|
fetchOriginPageviews(originPvData);
|
||||||
|
fetchProxyPageviews();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
});
|
} else { // still valid
|
||||||
|
displayPageviews(cache);
|
||||||
|
|
||||||
|
if (PvCache.isOriginCache() ) {
|
||||||
|
fetchProxyPageviews();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
fetchOriginPageviews(originPvData);
|
||||||
|
fetchProxyPageviews();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // endif
|
|
||||||
});
|
});
|
||||||
|
|
2
assets/js/dist/pageviews.min.js
vendored
2
assets/js/dist/pageviews.min.js
vendored
|
@ -1 +1 @@
|
||||||
function countUp(b,a,d){if(b<a){var c=new CountUp(d,b,a);if(!c.error){c.start()}else{console.error(c.error)}}}function countPV(f,e){var g=f.replace(/\/posts\//g,"").replace(/\//g,".html");var d=0;var c=f.replace(/posts\//g,"");for(var b=0;b<e.length;++b){var a=e[b][0];if(a==f||a==c||a.concat("/")==c||a.slice(a.lastIndexOf("/")+1)===g){d+=parseInt(e[b][1])}}return d}function tacklePV(e,f,d,b){var c=countPV(f,e);c=(c==0?1:c);if(!b){d.text(new Intl.NumberFormat().format(c))}else{var a=parseInt(d.text().replace(/,/g,""));if(c>a){countUp(a,c,d.attr("id"))}}}function displayPageviews(c){if(c===undefined){return}var a=getInitStatus();var b=c.rows;if($("#post-list").length>0){$(".post-preview").each(function(){var e=$(this).children("h1").children("a").attr("href");tacklePV(b,e,$(this).find(".pageviews"),a)})}else{if($(".post").length>0){var d=window.location.pathname;tacklePV(b,d,$("#pv"),a)}}}var getInitStatus=(function(){var a=false;return function(){if(a){return true}else{a=true;return false}}})();$(function(){if($(".pageviews").length>0){$.getJSON("/assets/data/pageviews.json",displayPageviews);$.getJSON("/assets/data/proxy.json",function(a){$.ajax({type:"GET",url:a.proxyUrl,dataType:"jsonp",jsonpCallback:"displayPageviews",error:function(b,d,c){console.log("Failed to load pageviews from proxy server: "+c)}})})}});
|
function countUp(b,a,d){if(b<a){var c=new CountUp(d,b,a);if(!c.error){c.start()}else{console.error(c.error)}}}function countPV(f,e){var g=f.replace(/\/posts\//g,"").replace(/\//g,".html");var d=0;var c=f.replace(/posts\//g,"");for(var b=0;b<e.length;++b){var a=e[b][0];if(a==f||a==c||a.concat("/")==c||a.slice(a.lastIndexOf("/")+1)===g){d+=parseInt(e[b][1])}}return d}function tacklePV(e,f,d,b){var c=countPV(f,e);c=(c==0?1:c);if(!b){d.text(new Intl.NumberFormat().format(c))}else{var a=parseInt(d.text().replace(/,/g,""));if(c>a){countUp(a,c,d.attr("id"))}}}function displayPageviews(c){if(c===undefined){return}var a=getInitStatus();var b=c.rows;if($("#post-list").length>0){$(".post-preview").each(function(){var e=$(this).children("h1").children("a").attr("href");tacklePV(b,e,$(this).find(".pageviews"),a)})}else{if($(".post").length>0){var d=window.location.pathname;tacklePV(b,d,$("#pv"),a)}}}var getInitStatus=(function(){var a=false;return function(){let ret=a;if(!a){a=true}return ret}})();var PvCache=(function(){const e="pv";const b="pv-created-date";const d="pv-type";var c={ORIGIN:"origin",PROXY:"proxy"};function a(g){return localStorage.getItem(g)}function f(g,h){localStorage.setItem(g,h)}return{getData:function(){return JSON.parse(localStorage.getItem(e))},saveOriginCache:function(g){f(e,g);f(d,c.ORIGIN);f(b,new Date().toJSON())},saveProxyCache:function(g){f(e,g);f(d,c.PROXY);f(b,new Date().toJSON())},isOriginCache:function(){return a(d)==c.ORIGIN},isProxyCache:function(){return a(d)==c.PROXY},isExpired:function(){if(PvCache.isOriginCache()){let date=new Date(a(b));date.setDate(date.getDate()+1);return Date.now()>=date.getTime()}else{if(PvCache.isProxyCache()){let date=new Date(a(b));date.setHours(date.getHours()+1);return Date.now()>=date.getTime()}}return false},getAllPagevies:function(){return PvCache.getData().totalsForAllResults["ga:pageviews"]},newerThan:function(g){return PvCache.getAllPagevies()>g.totalsForAllResults["ga:pageviews"]}}})();function fetchOriginPageviews(a){if(a===undefined){return}displayPageviews(a);PvCache.saveOriginCache(JSON.stringify(a))}function fetchProxyPageviews(){let proxy=JSON.parse(proxyData);$.ajax({type:"GET",url:proxy.url,dataType:"jsonp",jsonpCallback:"displayPageviews",success:function(b,c,a){PvCache.saveProxyCache(JSON.stringify(b))},error:function(a,c,b){console.log("Failed to load pageviews from proxy server: "+b)}})}$(function(){if($(".pageviews").length>0){let originPvData=pageviews?JSON.parse(pageviews):undefined;let cache=PvCache.getData();if(cache){if(PvCache.isExpired()){if(PvCache.isProxyCache()){if(originPvData){if(PvCache.newerThan(originPvData)){displayPageviews(cache)}else{fetchOriginPageviews(originPvData)}}fetchProxyPageviews()}else{if(PvCache.isOriginCache()){fetchOriginPageviews(originPvData);fetchProxyPageviews()}}}else{displayPageviews(cache);if(PvCache.isOriginCache()){fetchProxyPageviews()}}}else{fetchOriginPageviews(originPvData);fetchProxyPageviews()}}});
|
Loading…
Reference in a new issue