背景
当前获取信息的设备越来越多,比如平板电脑、智能手机,已经不是过去PC统治的年代了。所以很多网站为了提高用户体验根据不同的设备用不同的主题展现相同的数据。那么在roller中如何实现一个网站实现不同的主题呢?要考虑哪些因素?
有同学或许会说,这没什么的,用js+css或者借助一些框架就能根据不同的设备实现不同的主题。这是一种常见的方法,但在roller中可能要考虑的因素不同,机制不同。
原理
根据请求的URL不同让blog选择不同的主题。比如我们用域名www.example.com为PC访问展现内容,用m.example.com为智能手机展现内容。那么在roller中要根据域名的差异选择不同的主题。
怎么为roller设置域名映射参考我的文章:http://blog.csdn.net/rol2er/article/details/19081799
实现方法及说明
1、在类Weblog.java中增加一个参数用于传递请求的域名,以便后面做判断,以便达到修改代码最少的目的。
public String requestDomain;
用public是因为jpa如果有get/set方法就必须在db表中有对应的字段。
2、在合适的地方设置requestDomain
如果看过我前面的文章,你可能了解在roller中所有的页面请求都通过PageServlet.java 这个类。因此跟踪代码后知道要修改WeblogRequest类的getWeblog方法:
public Weblog getWeblog() { if(weblog == null && weblogHandle != null) { try { UserManager umgr = WebloggerFactory.getWeblogger().getUserManager(); weblog = umgr.getWebsiteByHandle(weblogHandle, Boolean.TRUE); } catch (WebloggerException ex) { log.error("Error looking up weblog "+weblogHandle, ex); } } //add weblog.requestDomain = request.getServerName(); return weblog; }
3、根据请求域名的不同选择不同的主题。在本文章前roller中weblog跟主题的关系是一对一的。在PageServlet中充满类似这样获取页面模板的调用:
page = weblog.getTheme().getTemplateByAction(ThemeTemplate.ACTION_PERMALINK);
我们要做的是进入getTheme()方法,看看后面的是什么逻辑。经过跟踪代码我们找到可以修改的地方ThemeManagerImpl.java的方法getTheme,如下:
public WeblogTheme getTheme(Weblog weblog) throws WebloggerException { if(weblog == null) return null; WeblogTheme weblogTheme = null; // if theme is custom or null then return a WeblogCustomTheme if(weblog.getEditorTheme() == null || WeblogTheme.CUSTOM.equals(weblog.getEditorTheme())) { weblogTheme = new WeblogCustomTheme(weblog); // otherwise we are returning a WeblogSharedTheme } else { ThemeManager themeMgr = roller.getThemeManager(); SharedTheme staticTheme = (SharedTheme) this.themes.get(weblog.getEditorTheme()); //add String otherTheme = WebloggerConfig.getProperty(weblog.requestDomain + ".other.theme.name"); if(otherTheme != null) { staticTheme = (SharedTheme) this.themes.get(otherTheme); }//end if(staticTheme != null) { weblogTheme = new WeblogSharedTheme(weblog, staticTheme); } else { log.warn("Unable to lookup theme "+weblog.getEditorTheme()); } } return weblogTheme; }
红色的是我增加的代码(add/end),通过配置文件来确定博客是否有多个主题,否则就按照原来的逻辑执行。
4、修改roller的缓存系统。
roller为了提高性能对页面做了缓存,如果不对缓存的内容根据domain做区别处理,那么被缓存的一份内容可能被不同的设备获取到,届时智能手机将看到pc专用页面,pc将获取智能手机的专用页面。这种情况是非常糟糕的。
那么如何解决呢?只要修改两个地方。对SiteWideCache类和WeblogPageCache类的下面方法增加红色代码即可。
public String generateKey(WeblogPageRequest pageRequest) { StringBuffer key = new StringBuffer(); //add key.append(pageRequest.getWeblog().requestDomain);//end key.append(this.CACHE_ID).append(".").append(pageRequest.getLocaleInstance().toString()).append(":"); key.append("page/"); key.append(pageRequest.getWeblogHandle()); //.... }
最后
大概的思路是这样,如果你对roller比较好的了解,有更好的方案,欢迎交流。