2019独角兽企业重金招聘Python工程师标准>>>
一个建站系统,如果想要在政府网站中使用,个性化页面通常是一个评测指标,所以无法避免,必须面对。
从技术层面讲,一旦涉及个性化,就会引入cookie,session等问题,这些都是cache的对立面,会对程序的性能造成严重影响。据我所了解,一般系统都是通过定制方式来解决这个问题。对于单实例系统这是可行的,但是对于多站点系统呢?
不能事先假设建站系统的使用者(站点设计者)的能力,强迫他们使用复杂的解决方案。这篇文章是我对这个问题的解决方案,只是一种可行的,主要是应付某种评测的解决方案。同时作为设计者的个性化帮助文档。
1、个性化入口
在建站系统中划出一个url空间作为个性化的入口。/wpersonal(我就把他定死了),对于我们的建站系统来说,就是在后台的“站点设计”页面中建立一个wpersonal目录,然后将你所需要的模板放在这个目录中即可。
您可以控制登陆方式,避免用户在登陆界面选择。比如:/wpersonal?dtLogin=true&loginMethod=qq,/wpersonal?dtLogin=true&loginMethod=LocalLogin,登出用 /verifyMe?dowhat=logout
a、认证,当浏览器指向/wpersonal时,如果用户已经登录,那么就显示,反之引导用户进入登录页面,登录之后返回此处。
b、默认个性化主页,如果个性化仅仅设计了一个主页面,通过css和其它技术展现个性化,那么只要将个性化的链接设置成某个模板即可。比如:/wpersonal/index.ftl。有些公司对css很感冒(招募精通css的意味着付出更多的工资),更喜欢用不同的页面来展示个性化成分,比如:/wpersional/style1.ftl,/wpersonal/style2.ftl。在这种情况下,需要在后台“个性化”元素里面定义一些记录。稍后会介绍“个性化元素”。
2、个性化内容
个性化内容非常宽泛,作为建站系统的设计者无法预知站点设计者的个性化思路。作为建站系统的设计者,当然希望能够满足站点设计者的所有要求,但这个很难做到(因为我不够聪明)。我只能给设计者提供以下设计思路,至于是否合理,可以在使用过程中相互交流。
个性化记录属性有:siteId,cat,f1,f2,f3,f4,f5,uniqueNumber
siteId是long,站点ID
cat:类别
uniqueFieldNum : 从左到右几个字段构成站点个性化记录的唯一性。(用户不会拥有矛盾的个性化条目,比如背景红色,背景蓝色不会同时拥有。)
注意,除了siteId,这些字段的解释是不固定的。作为站点设计者,你自己去添加自己去解释。下面我来提供一种解释方案仅供参考。
要求:
1、有两个风格的页面共用户选择,style1.ftl,style2.ftl
2、每个页面中显示用户选择要显示的内容块。
处理/wpersonal的servlet采取一种约定来处理默认主页的问题。当用户请求/wpersonal时,显示哪一张张页面是这样决定的:
(为了便于书写,个性化记录用json格式表示)
1、如果用户已经有了保存的偏好,比如:{siteId:5566,cat:'homepage',f1:'style1.ftl'},那么就显示wpersonal/style1.ftl
2、如果没有,那么就找到{siteId:5566,cat:'homepage',f1:'anydefault.ftl',f2:'default'},这个值必须在后台事先添加。
3、如果没有处理第二步,那么页面会提示找不到默认模板。
模板的选择问题解决了,接下来是如何显示用户定义的块呢?个性化记录的设计如下:
{siteId:5566,cat:'section',f1:'1234',uniqueNumber:3},这里f1的值是目录的ID,如果用户的自定义条目中有这个条目,就显示这个目录,反之则不显示。在freemarker模板里面可以这么书写:
<# if(siteUserSettings.findByF1Mine('section','1234')??)>
说明用户选择了这个目录,显示出来。这是最简单的情况,有或者没有而已。不牵涉到在哪里,怎么显示等等。
</#if>
接下来是如何保存用户的偏好,这是个单调而重复的工作,我专门为此写了一个基于yui的js插件,当然也是基于最简单的情况而写,你可以查看js源码,写自己的插件以满足更复杂的要求。
下面以一个网站作为说明:
1、进入http://www.fhsafety.gov.cn,点击上面的“登陆个性化“,如果用户没有登陆,将引导到登陆页面,登陆后返回个性化页面。
2、在后台的”网络域名-》个性化设置“,预先加入以下条目。
组 | f1 | f2 | f3 |
homepage | style100.ftl | default | 青青河草 |
homepage | style101.ftl | | 蓝色忧郁 |
section | 84224 | 安全动态 | |
section | 84225 | 通知公告 | |
section | 84135 | 矿山监管 | |
| | | |
| | | |
这是个性化选择页面:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta charset="utf-8">
<title>WebCus Form Test Suite</title>
</head>
<body class="yui3-skin-sam"><div id="webcus-c"><script type="text/x-template"><form action="#"><p>风格选择:</p><% Y.Array.each(this.webcuss.getByCat("homepage"),function(one){ %><label><input type="radio" name="theme" id="webcusitem-<%= one.id %>"<%= one.mine ? "checked" : "" %>><%= one.f3 %></label><br/><% }); %><p>----------------------------------</p><p>栏目选择:</p><% Y.Array.each(this.webcuss.getByCat("section"),function(one){ %><label><input type="checkbox" id="webcusitem-<%= one.id %>"<%= one.mine ? "checked" : "" %>><%= one.f2 %></label><br/><% }); %><input type="submit" value="保存" style="margin:10px 30px;"></form></script>
</div><script src="${yuiSeed}" type="text/javascript"></script>
<script type="text/javascript"><#include "webcus-form-page.js"></script>
<script type="text/javascript">_WEBCUS_FORM({siteId:${site.id?c},container:'#webcus-c',afterSave: function(){alert('以保存!'); //这里可以使用任意js代码。location.href = "/wpersonal";},updateCats:[]});
</script></body>
</html>
这是style100.ftl
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta charset="utf-8">
<title>WebCus Form Test Suite</title>
</head>
<body class="yui3-skin-sam"><p>style100,默认,<a href="webcus_form.ftl">设定个性化</a></p><#if (siteUserSettings.hasMyCustoms())> <#-- 如果有个性化设置,说明用户至少操作过 --><#if siteUserSettings.hasMyCustoms("section")> <#-- 虽然用户曾经自定义过,但有可能仅仅修改了主题什么的,还要判断有没有自定义目录 --><#list siteUserSettings.findByCatMine("section") as mc><#assign sec = site.findSection(mc.f1)><div><h2>${sec.name}:</h2><ol><#list sec.articlesPage(1,8) as ar><li><a href="${ar.url}">${ar.getTitle(20,"...")}</a></li></#list></ol></div></#list><#else><#list siteUserSettings.findByCat("section") as mc> <#-- 注意,这里是findByCat,而不是findByCatMine 全部显示 --><#assign sec = site.findSection(mc.f1)><div><h2>${sec.name}:</h2><ol><#list sec.articlesPage(1,8) as ar><li><a href="${ar.url}">${ar.getTitle(20,"...")}</a></li></#list></ol></div></#list></#if>
<#else><#-- 这里当然是全部显示,因为用户还没有自定义操作过,当然你可以决定此种情况下,显示哪些内容 --><#list siteUserSettings.findByCat("section") as mc><#assign sec = site.findSection(mc.f1)><div><h2>${sec.name}:</h2><ol><#list sec.articlesPage(1,8) as ar><li><a href="${ar.url}">${ar.getTitle(20,"...")}</a></li></#list></ol></div></#list></#if></body>
</html>
有没有发现模板里有重复代码?请考虑使用freemark的宏。
您可以登录建站系统,自己尝试:http://sb.m3958.com