Skip to content

Commit

Permalink
✨ umami 插件挂载统计数据
Browse files Browse the repository at this point in the history
  • Loading branch information
mobeicanyue authored and zkqiang committed Apr 1, 2024
1 parent c4f7ac7 commit fa4319d
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 27 deletions.
51 changes: 32 additions & 19 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -260,21 +260,6 @@ web_analytics:
google:
measurement_id:

# Umami Analytics,src 和 data-website-id 是必填项,其他可选
# Umami Analytics, src and data-website-id are required, others are optional
umami:
# umami js 文件地址,需要在 umami 后台创建站点后获取
# umami js file url, get after create website in umami
src:
# umami 的 website id,需要在 umami 后台创建站点后获取
# umami website id, get after create website in umami
data_website_id:
# 如果你只想跟踪器跟踪特定的域名,你可以将它们添加到你的跟踪器脚本中。这是一个逗号分隔的域名列表。
# 如果你在一个分阶段、开发的环境中工作,这会很有帮助。避免统计 localhost。
# If you want the tracker to only run on specific domains, you can add them to your tracker script. This is a comma delimited list of domain names.
# Helps if you are working in a staging/development environment. Avoids tracking localhost.
data_domains:

# 腾讯统计的 H5 App ID,开启高级功能才有cid
# Tencent analytics, set APP ID
# See: https://mta.qq.com/h5/manage/ctr_app_manage
Expand Down Expand Up @@ -307,6 +292,34 @@ web_analytics:
# If true, ignore localhost & 127.0.0.1
ignore_local: false

# Umami Analytics,仅支持自部署。如果要展示 PV UV 需要填写所有配置项,否则只填写 `src` 和 `website_id` 即可
# Umami Analytics, only Self-host support. If you want to display PV UV need to set all config items, otherwise only set 'src' and 'website_id'
# See: https://umami.is/docs/authentication
umami:
# umami js 文件地址,需要在 umami 后台创建站点后获取
# umami js file url, get after create website in umami
src:

# umami 的 website id,需要在 umami 后台创建站点后获取
# umami website id, get after create website in umami
website_id:

# 如果你只想统计特定的域名可以填入此字段,多个域名通过逗号分隔,这可以避免统计 localhost。
# If you only want to tracker to specific domains you can fill in this field, multiple domain names are separated by commas, which can avoid tracker localhost
domains:

# 用于统计 PV UV 的开始时间,格式为 "YYYY-MM-DD"
# statistics on the start time, the format is "YYYY-MM-DD"
start_time: 2024-01-01

# 新建一个 umami viewOnly 用户,然后通过 login api 获取该用户 token
# create an umami viewOnly user, and then get user token through the login api
token:

# 填写 umami 部署的服务器地址,如 "https://umami.example.com"
# server url of umami deployment, such as "https://umami.example.com"
api_server:

# Canonical 用于向 Google 搜索指定规范网址,开启前确保 hexo _config.yml 中配置 `url: http://yourdomain.com`
# Canonical, to specify a canonical URL for Google Search, need to set up `url: http://yourdomain.com` in hexo _config.yml
# See: https://support.google.com/webmasters/answer/139066
Expand Down Expand Up @@ -453,9 +466,9 @@ footer:
statistics:
enable: false

# 统计数据来源,使用 leancloud 需要设置 `web_analytics: leancloud` 中的参数;使用 busuanzi 不需要额外设置,但是有时不稳定,另外本地运行时 busuanzi 显示统计数据很大属于正常现象,部署后会正常
# Data source. If use leancloud, you need to set the parameter in `web_analytics: leancloud`
# Options: busuanzi | leancloud
# 统计数据来源,使用 leancloud, umami 需要设置 `web_analytics` 中对应的参数;使用 busuanzi 不需要额外设置,但是有时不稳定,另外本地运行时 busuanzi 显示统计数据很大属于正常现象,部署后会正常
# Data source. If use leancloud, umami, you need to set the parameter in `web_analytics`
# Options: busuanzi | leancloud | umami
source: "busuanzi"

# 国内大陆服务器的备案信息
Expand Down Expand Up @@ -598,7 +611,7 @@ post:
enable: false
# 统计数据来源
# Data Source
# Options: busuanzi | leancloud
# Options: busuanzi | leancloud | umami
source: "busuanzi"

# 在文章开头显示文章更新时间,该时间默认是 md 文件更新时间,可通过 front-matter 中 `updated` 手动指定(和 date 一样格式)
Expand Down
22 changes: 20 additions & 2 deletions layout/_partials/footer/statistics.ejs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div class="statistics">
<% var pv_texts = (theme.footer.statistics.pv_format || __('footer.pv')).split('{}') %>
<% var uv_texts = (theme.footer.statistics.uv_format || __('footer.uv')).split('{}') %>
<% let pv_texts = (theme.footer.statistics.pv_format || __('footer.pv')).split('{}') %>
<% let uv_texts = (theme.footer.statistics.uv_format || __('footer.uv')).split('{}') %>

<% if (theme.footer.statistics.source === 'leancloud') { %>
<% if (pv_texts.length >= 2) { %>
Expand Down Expand Up @@ -35,5 +35,23 @@
</span>
<% } %>
<% import_js(theme.static_prefix.busuanzi, 'busuanzi.pure.mini.js', 'defer') %>
<% } else if (theme.footer.statistics.source === 'umami') { %>
<% if (pv_texts.length >= 2) { %>
<span id="umami-site-pv-container" style="display: none">
<%- pv_texts[0] %>
<span id="umami-site-pv"></span>
<%- pv_texts[1] %>
</span>
<% } %>
<% if (uv_texts.length >= 2) { %>
<span id="umami-site-uv-container" style="display: none">
<%- uv_texts[0] %>
<span id="umami-site-uv"></span>
<%- uv_texts[1] %>
</span>
<% } %>
<% import_js(theme.static_prefix.internal_js, 'umami-view.js', 'defer') %>
<% } %>

</div>
17 changes: 11 additions & 6 deletions layout/_partials/plugins/analytics.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,17 @@
</script>
<% } %>
<% if(theme.web_analytics.umami && theme.web_analytics.umami.src && theme.web_analytics.umami.data_website_id) { %>
<!-- Umami Analytics -->
<script async defer src="<%= theme.web_analytics.umami.src %>" data-website-id="<%= theme.web_analytics.umami.data_website_id %>"
<% if (theme.web_analytics.umami.data_domains) { %> data-domains="<%= theme.web_analytics.umami.data_domains %>" <% } %>
<% if (theme.web_analytics.follow_dnt) { %> data-do-not-track="<%= theme.web_analytics.follow_dnt %>" <% } %>
></script>
<% if(theme.web_analytics.umami && theme.web_analytics.umami.src && theme.web_analytics.umami.website_id) { %>
<script async>
if (!Fluid.ctx.dnt) {
let umami = document.createElement('script');
umami.async = true;
umami.src = "<%= theme.web_analytics.umami.src %>";
umami.setAttribute("data-website-id", "<%= theme.web_analytics.umami.website_id %>");
umami.setAttribute("data-domains", "<%= theme.web_analytics.umami.domains %>");
document.head.appendChild(umami);
}
</script>
<% } %>
<% if(theme.web_analytics.tencent && theme.web_analytics.tencent.sid && theme.web_analytics.tencent.cid) { %>
Expand Down
8 changes: 8 additions & 0 deletions layout/_partials/post/meta-top.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,20 @@
<%- views_texts[0] %><span id="leancloud-page-views"></span><%- views_texts[1] %>
</span>
<% import_js(theme.static_prefix.internal_js, 'leancloud.js', 'defer') %>
<% } else if (theme.post.meta.views.source === 'busuanzi') { %>
<span id="busuanzi_container_page_pv" style="display: none">
<i class="iconfont icon-eye" aria-hidden="true"></i>
<%- views_texts[0] %><span id="busuanzi_value_page_pv"></span><%- views_texts[1] %>
</span>
<% import_js(theme.static_prefix.busuanzi, 'busuanzi.pure.mini.js', 'defer') %>
<% } else if (theme.post.meta.views.source === 'umami') { %>
<span id="umami-page-views-container" class="post-meta" style="display: none">
<i class="iconfont icon-eye" aria-hidden="true"></i>
<%- views_texts[0] %><span id="umami-page-views"></span><%- views_texts[1] %>
</span>
<% import_js(theme.static_prefix.internal_js, 'umami-view.js', 'defer') %>
<% } %>
<% } %>
</div>
Expand Down
99 changes: 99 additions & 0 deletions source/js/umami-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// 从配置文件中获取 umami 的配置
const website_id = CONFIG.web_analytics.umami.website_id;
// 拼接请求地址
const request_url = `${CONFIG.web_analytics.umami.api_server}/websites/${website_id}/stats`;

const start_time = new Date(CONFIG.web_analytics.umami.start_time).getTime();
const end_time = new Date().getTime();
const token = CONFIG.web_analytics.umami.token;

// 检查配置是否为空
if (!website_id) {
throw new Error("Umami website_id is empty");
}
if (!request_url) {
throw new Error("Umami request_url is empty");
}
if (!start_time) {
throw new Error("Umami start_time is empty");
}
if (!token) {
throw new Error("Umami token is empty");
}

// 构造请求参数
const params = new URLSearchParams({
startAt: start_time,
endAt: end_time,
});
// 构造请求头
const request_header = {
method: "GET",
headers: {
"Content-Type": "application/json",
"x-umami-api-key": "oZKCH3msvqt10VlXKwoJvHclmaS4bVx0",
},
};

// 获取站点统计数据
async function siteStats() {
try {
const response = await fetch(`${request_url}?${params}`, request_header);
const data = await response.json();
const uniqueVisitors = data.uniques.value; // 获取独立访客数
const pageViews = data.pageviews.value; // 获取页面浏览量

let pvCtn = document.querySelector("#umami-site-pv-container");
if (pvCtn) {
let ele = document.querySelector("#umami-site-pv");
if (ele) {
ele.textContent = pageViews; // 设置页面浏览量
pvCtn.style.display = "inline"; // 将元素显示出来
}
}

let uvCtn = document.querySelector("#umami-site-uv-container");
if (uvCtn) {
let ele = document.querySelector("#umami-site-uv");
if (ele) {
ele.textContent = uniqueVisitors;
uvCtn.style.display = "inline";
}
}
} catch (error) {
console.error(error);
return "-1";
}
}

// 获取页面浏览量
async function pageStats(path) {
try {
const response = await fetch(`${request_url}?${params}&url=${path}`, request_header);
const data = await response.json();
const pageViews = data.pageviews.value;

let viewCtn = document.querySelector("#umami-page-views-container");
if (viewCtn) {
let ele = document.querySelector("#umami-page-views");
if (ele) {
ele.textContent = pageViews;
viewCtn.style.display = "inline";
}
}
} catch (error) {
console.error(error);
return "-1";
}
}

siteStats();

// 获取页面容器
let viewCtn = document.querySelector("#umami-page-views-container");
// 如果页面容器存在,则获取页面浏览量
if (viewCtn) {
let path = window.location.pathname;
let target = decodeURI(path.replace(/\/*(index.html)?$/, "/"));
pageStats(target);
}

0 comments on commit fa4319d

Please sign in to comment.