Homeland Ruby-China 源码追踪: 小贴士功能分析

lazybios · 2015年08月12日 · 最后由 xiao__liang 回复于 2016年05月16日 · 2459 次阅读

什么是个小贴士,看这里!

小贴士

小贴士会在 PC 端的 topics 列表页与内容页出现,样子如上。既然我们能看到小贴士,那么我们就直接通过ack来定位代码位置,ack 小帖士 找到小贴士的 view 文件app/views/topics/_sidebar_box_tips.html.erb,发现这里是 partial 样式,再来通过ack sidebar_box_tips都有谁调用了这个 partial,结果发现分别是下面两个文件:

  • app/views/topics/_sidebar_for_topic_index.html.erb
  • app/views/topics/show.html.erb

正好是 topic 的列表页和内容页,我们再回到app/views/topics/_sidebar_box_tips.html.erb文件中看看数据是如何存储和传递的。


<div class="panel panel-default">
  <div class="panel-heading">小帖士</div>
  <div class="panel-body">
    <%= random_tips %>
  </div>
</div>

发现此处并没有我们要的结果,而是调用了一个叫random_tips方法,这个方法明显不是系统方法,所以可以断定是 helper 方法,再来继续追踪random_tips,发现确实是在app/helpers/application_helper.rb中定义的。


def random_tips
  tips = SiteConfig.tips
  return EMPTY_STRING if tips.blank?
  tips.split("\n").sample

数据存储在 Mongo 中的 SiteConfig 文档从,SiteConfig.tips取出数据、判空、返回显示到页面中,这里还有个地方需要指出就是在对于移动端和 PC 端的显示方法。小贴士的显示逻辑是通过mobile?方法判断用户客户端类型是否为移动设备,过滤显示,view 代码如下:


<% if !mobile? %>
  <div class="sidebar col-md-3">
    <%= render "sidebar_box_tips" %>
    <%= render "sidebar_box_node_recent_topics", topic: @topic %>
  </div>
<% end %>

通过ack 'mobile\?'查找方法定义,发现也定义在app/helpers/application_helper.rb中。


MOBILE_USER_AGENTS =  'palm|blackberry|nokia|phone|midp|mobi|symbian|chtml|ericsson|minimo|' +
                      'audiovox|motorola|samsung|telit|upg1|windows ce|ucweb|astel|plucker|' +
                      'x320|x240|j2me|sgh|portable|sprint|docomo|kddi|softbank|android|mmp|' +
                      'pdxgw|netfront|xiino|vodafone|portalmmm|sagem|mot-|sie-|ipod|up\\.b|' +
                      'webos|amoi|novarra|cdm|alcatel|pocket|iphone|mobileexplorer|mobile'
def mobile?
  agent_str = request.user_agent.to_s.downcase
  return false if agent_str =~ /ipad/
  agent_str =~ Regexp.new(MOBILE_USER_AGENTS)
end

原理也简单,使用正则判断 reques 头部中 user_agent 类型是否在MOBILE_USER_AGENTS里,另外指出的是这里将 ipad 也按照 PC 端的方式处理了,想必是因为 ipad 这类设备的尺寸已经可以当类 PC 显示了。MOBILE_USER_AGENTS列表好全,这个方法可以单独提取出来放到工具箱里,在后面的项目中使用。

小贴士的代码算是追踪完了,对我这个 Rails newbie 来说学到不少东西。希望后面自己能持续坚持下来!

很有料,学习中...

需要 登录 后方可回复, 如果你还没有账号请 注册新账号