经过几个小时的无果尝试后,我想请求大家通过简单的设置提供一点帮助:
对于我使用 apache2 http 服务器运行的一堆 Web 应用程序和站点,我使用 Piwik进行简单的统计概述。效果很好。让我烦恼的是,对于每个额外的应用程序/页面以及每次更新/升级,我都必须小心手动维护 piwik 所需的 javascript 代码,以将其包含到 html 标记中。
为了简化维护,我希望 apache 添加该代码:我想使用一些 apache 模块:mod_filter、mod_env、mod_substitute 和 mod_include。这个想法是通过过滤器将 piwik 代码注入(inject)所有交付的 html 文件。该过滤器使用替换来前置 </body>
带有占位符的标签。该占位符又是一个由服务器端包含处理的 sgml 标记。该包含最终用 piwik 代码替换占位符,该代码以动态方式给出所需的数字站点 id。
因此,配置新虚拟主机时剩下的就是在 apache 配置中指定两行:
- 包含存储在小文件中的过滤器设置
- 通过设置环境变量指定数字 piwik 站点 ID
不再需要摆弄应用程序内的模板文件!
<小时/>我非常接近解决方案,但缺少一步......
也许你们中的一些专家发现了我所缺少的!
<小时/>虚拟主机的(非常简单的)配置:
<VirtualHost *:80>
ServerAdmin www@domain.here
ServerName some.domain.here
# include local piwik setup
SetEnv PIWIK_ID 5
Include /etc/apache2/vhosts.d/_internal.inc
DocumentRoot /some/path/here
<Directory "/some/path/here">
Options None
AllowOverride none
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
上面包含的(缩短的)配置文件:
# some internal resources
<Directory "/srv/www/internal">
Options None
AllowOverride None
Order deny,allow
Allow from all
</Directory>
# ----------
# internal requests to include the piwik tracking code at the bottom of every html page
# prepare required filters
FilterDeclare filter_PIWIK
FilterProvider filter_PIWIK SUBSTITUTE resp=Content-Type $text/html
FilterProvider filter_PIWIK INCLUDES resp=Content-Type $text/html
FilterChain filter_PIWIK SUBSTITUTE 's|</body>|<!--#include virtual="/piwik" --></body>|ni'
# map virtual request to the file system
Alias /piwik /srv/www/internal/piwik.php
<小时/>
最后一个文件 /srv/www/internal/piwik.php
Alias
中引用多于:
这是提供 piwik 代码的文件。
它就像 piwik 本身计算的那样,除了一件事:
数字站点索引动态替换为环境变量中的值
<?php
define('piwikBase','domain.here/stats/');
define('piwikSite',apache_getenv('PIWIK_ID'));
if(is_numeric(piwikSite)){
?>
<!-- Piwik: begin tracking code -->
<script type="text/javascript">
var pkBaseURL = (("https:" == document.location.protocol) ? "https://<?php echo piwikBase; ?>" : "http://<?php echo piwikBase; ?>");
document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
</script><script type="text/javascript">
try {
var piwikTracker = Piwik.getTracker(pkBaseURL + "piwik.php", <?php echo piwikSite; ?>);
piwikTracker.trackPageView();
piwikTracker.enableLinkTracking();
} catch( err ) {}
</script><noscript><p><img src="http://<?php echo piwikBase; ?>piwik.php?idsite=<?php echo piwikSite; ?>" style="border:0" alt="" /></p></noscript>
<!-- Piwik: end tracking code -->
<?php } else { ?>
<!-- invalid piwik site id: <?php echo piwikSite;?> -->
<?php } ?>
到目前为止我所做的工作:
- 基于 php 的动态 piwik scniplet 正在工作,我可以使用浏览器调用它,并查看 html 标记源中的代码,其中包含从配置中定义的环境变量获取的数字 ID,用于测试目的。另外,当我以这种方式指定 nin 数字 id 时,我得到了预期的占位符
<!-- invalid piwik site id: ... -->
- 过滤器通常有效(应用):
</body>
标记被替换为占位符。我可以通过注释掉在开头添加 INCLUDES 指令的 FilterProvider 来检查这一点。在这种情况下,我会在生成的 html 标记中看到占位符。 - FilterProvider 实际上是由 apache 识别并执行的:在我遇到关于缺少
Options +Includes
的错误之前在配置之类的事情都搞清楚之后,apache就不再提示了。当上面提到的 FilterProvider 没有被注释掉时,占位符也会被再次删除。所以我假设包含过程正在工作。 - 显然问题不在于服务器端包含引用了 php 脚本。我没有收到任何错误消息,并且使用静态文件进行的测试没有显示任何差异。
看起来设置工作正常,没有抛出错误,重写日志中没有任何奇怪的东西。然而,尽管包含过滤器显然有效,但我期望包含的内容是空的。第一个 SUBSTITUTE 步骤插入的占位符将再次被第二个 INCLUDE 步骤替换。但不幸的是由于内容为空,因此将其删除。我不知道为什么。
最佳答案
好吧,我自己找到了答案。这是我第六次尝试挖掘这个问题,最后我成功了。我所要做的就是更改过滤器代码的定义和用法。其他一切都很好:
FilterDeclare PIWIK_token
FilterProvider PIWIK_token SUBSTITUTE resp=Content-Type $text/html
SUBSTITUTE 's|</body>|<!--#include virtual="/piwik" --></body>|ni'
FilterDeclare PIWIK_code
FilterProvider PIWIK_code INCLUDES resp=Content-Type $text/html
FilterChain PIWIK_token PIWIK_code
我很惊讶没有人尝试这样的事情。现在,我可以手动删除所有插入的脚本片段和很多地方,而无需在升级或添加页面或整个网站时再次考虑它们。我所需要的只是使用提到的这两行来指定站点 piwik id。伟大的。
2013 年 1 月 23 日更新:
我已经使用这个解决方案几个星期了,没有遇到任何设置问题。所以我做了一个简短的描述。也许这对某人有帮助:
关于apache - 通过 apache 服务器内的服务器端过滤动态包含 piwik 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13637714/