Solo 皮肤切换

本贴最后更新于 1819 天前,其中的信息可能已经事过景迁

本文是《Solo 从设计到实现》的一个章节,该系列文章将介绍 Solo 这款 Java 博客系统是如何从无到有的,希望大家能通过它对 Solo 从设计到实现有个直观地了解、能为想参与贡献的人介绍清楚项目,也希望能为给重复发明重新定义博客系统的人做个参考 ❤️

后台切换

管理员可以在管理后台切换皮肤,并且可以为桌面端和移动端指定不同的皮肤。配置保存在 option 表中,对应的 id 为 skinDirNamemobileSkinDirName

设置好以后选用的皮肤名称会被写入 Cookie,以便前台请求时可以快速获取到皮肤信息,避免查库。

后台切换皮肤请求处理 SkinConsole#updateSkin 方法:

public void updateSkin(final RequestContext context) { final JsonRenderer renderer = new JsonRenderer(); context.setRenderer(renderer); try { final JSONObject requestJSONObject = context.requestJSON(); final JSONObject skin = requestJSONObject.getJSONObject(Option.CATEGORY_C_SKIN); final JSONObject ret = new JSONObject(); renderer.setJSONObject(ret); skinMgmtService.updateSkin(skin); final Response response = context.getResponse(); final Cookie skinDirNameCookie = new Cookie(Common.COOKIE_NAME_SKIN, skin.getString(Option.ID_C_SKIN_DIR_NAME)); skinDirNameCookie.setMaxAge(60 * 60); // 1 hour skinDirNameCookie.setPath("/"); response.addCookie(skinDirNameCookie); final Cookie mobileSkinDirNameCookie = new Cookie(Common.COOKIE_NAME_MOBILE_SKIN, skin.getString(Option.ID_C_MOBILE_SKIN_DIR_NAME)); mobileSkinDirNameCookie.setMaxAge(60 * 60); // 1 hour mobileSkinDirNameCookie.setPath("/"); response.addCookie(mobileSkinDirNameCookie); ret.put(Keys.STATUS_CODE, true); ret.put(Keys.MSG, langPropsService.get("updateSuccLabel")); } catch (final ServiceException e) { LOGGER.log(Level.ERROR, e.getMessage(), e); final JSONObject jsonObject = new JSONObject().put(Keys.STATUS_CODE, false); renderer.setJSONObject(jsonObject); jsonObject.put(Keys.MSG, langPropsService.get("updateFailLabel")); } }

前台切换

为了方便预览皮肤,访客可从前台自行切换皮肤,仅在首页路径下有效:/skin=xxx。实现逻辑是在 IndexProcessor#showIndex 时获取 skin 参数,然后用该参数指定的皮肤进行渲染,并写入 Cookie 以备其他页面请求使用。

String specifiedSkin = Skins.getSkinDirName(context); if (StringUtils.isBlank(specifiedSkin)) { final JSONObject skinOpt = optionQueryService.getSkin(); specifiedSkin = Solos.isMobile(request) ? skinOpt.optString(Option.ID_C_MOBILE_SKIN_DIR_NAME) : skinOpt.optString(Option.ID_C_SKIN_DIR_NAME); } request.setAttribute(Keys.TEMAPLTE_DIR_NAME, specifiedSkin); Cookie cookie; if (!Solos.isMobile(request)) { cookie = new Cookie(Common.COOKIE_NAME_SKIN, specifiedSkin); } else { cookie = new Cookie(Common.COOKIE_NAME_MOBILE_SKIN, specifiedSkin); } cookie.setMaxAge(60 * 60); // 1 hour cookie.setPath("/"); response.addCookie(cookie);

解析所需皮肤

请求到服务端后会优先从 Cookie 中获取皮肤名,如果为空再从查 option 表获取管理员指定的皮肤。同时也会判断是否是移动端,移动端请求需要使用移动端指定皮肤。实现代码在 SkinHandler#resolveSkinDir:

private void resolveSkinDir(final Request request) { String skin = Skins.getSkinDirNameFromCookie(request); if (StringUtils.isBlank(skin)) { final BeanManager beanManager = BeanManager.getInstance(); final OptionQueryService optionQueryService = beanManager.getReference(OptionQueryService.class); final JSONObject skinOpt = optionQueryService.getSkin(); if (Solos.isMobile(request)) { if (null != skinOpt) { skin = skinOpt.optString(org.b3log.solo.model.Option.ID_C_MOBILE_SKIN_DIR_NAME); } else { skin = org.b3log.solo.model.Option.DefaultPreference.DEFAULT_MOBILE_SKIN_DIR_NAME; } } else { if (null != skinOpt) { skin = skinOpt.optString(org.b3log.solo.model.Option.ID_C_SKIN_DIR_NAME); } else { skin = org.b3log.solo.model.Option.DefaultPreference.DEFAULT_SKIN_DIR_NAME; } } } request.setAttribute(Keys.TEMAPLTE_DIR_NAME, skin); }
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1436 引用 • 10059 回帖 • 491 关注
  • 设计
    116 引用 • 797 回帖 • 1 关注
  • 皮肤
    38 引用 • 382 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • ruoxi520chenxi

    问题来了,现在用的皮肤不能适配最新版的 SOLO,访问 505,我怎么再代码里面修改成默认皮肤呢

    1 回复
  • 88250

    /start 登录后台,然后皮肤管理里调整即可。

    1 回复
  • ruoxi520chenxi

    我没有配置 Latke

    1 回复
  • 88250

    我不明白你的意思,如果是报 Latke 配置错误,请参考用户指南。

    2 回复
  • ruoxi520chenxi

    域名后加**/start** 访问提示 Latke 配置错误

  • ruoxi520chenxi

    用户指南了没有看到配置 latke 的地方

    1 回复
  • 88250

    在报错页面上应该能找到解决问题的文档链接。

请输入回帖内容 ...