Logo

refinerycms开发总结

avatar cain 27 May 2016

refinerycms主要的任务是做内容管理系统,就是有前台和后台的内容页面管理。其中也遇到了很多棘手的问题,有时侯甚至不知道refinerycms里面已经集成好的,然后就是不停的造轮子,幸好有团队大神指导,要不使用refinerycms感觉就没有什么意义了。下面是做项目时有关model/controller的修改,view的覆盖,后台功能的扩展方面的总结。

关于model的修改

refinerycms里面可能需要集成博客功能进去,如果想修改model的内容就需要通过decorator的方式去进行修改。该方式是指在refinerycms中对gem内置的model、controller使用decorator(装饰器)模式,reopen class来覆盖class的内容,文件名要求符合 app/decorators/models/refinery/${refinery_engine_name}/#{model_name}_decorator.rb, 代码例子如下

Refinery::Blog::Post.class_eval do
  scope :pinned, -> { where(:pinned => true) }
end

需要添加数据库字段

如果需要修改数据库字段,则需要对应的迁移任务。然后利用和model中类似的方式打开对应的Controller类,在其中进行编写,对应有两种方式,代码例子如下(这里添加了一个pinned字段):

  • 可以创建一个controller,文件为 /app/decorators/controllers/refinery/blog/posts_controller_decorator.rb
Refinery::Blog::Admin::PostsController.class_eval do
  def post_params
    params.require(:post).permit(:title, :body, :custom_teaser, :tag_list,
      :draft, :published_at, :custom_url, :user_id, :browser_title,
      :meta_description, :pinned, :source_url, :source_url_title, :category_ids => [], :images_attributes => [:id, :caption])
  end
end

post_params方法会覆盖原生定义该方法。

自定义页面

可以通过执行命令rake refinery:override view=页面进行对应的文件生成,该命令作用主要是复制refinerycms里面的文件到rails项目中,然后可以进行相应页面的更改,在加载时会自动覆盖refinerycms默认的页面。在项目中由于博客需要有置顶功能,但是置顶的博客限制在了4篇,所以需要在后台管理那里添加列出置顶博客的功能选项供查看。由于需要改动页面,所以需要把refinerycms这个engine里的文件复制出来编辑覆盖原生的内容。执行rake refinery:override view=refinery/blog/admin/_submenu,然后打开页面编辑就可以了。

refinerycms在页面的head标签中的meta标签的自定义

<%= raw %() if @meta.meta_description.present? -%>

需要解决的问题是在查看博客内容时可以显示meta_description的内容。为了编辑方便,在博客中的摘要和内容是放在一起,通过分隔符分开来的。在index页面如果需要显示摘要部分,只需要提取分隔开的摘要部分的内容。这就带来了一个问题,编辑时meta_description的内容为空,但是又想用摘要部分作为meta_description的内容,这时只能是自己定义一个了。

问题分析

  • 首先@meta根据加载页面的不同加载到不同model的对象,在一般页面加载到的是PagePresenter的对象,其中继承自BasicPresenter,在这个类中定义了meta_description属性,这个属性可以在后台的/refinery/pages页面的页面编辑中的Advanced options中编辑该属性。
  • 如果是查看博客内容的页面,@meta是PostPresenter的对象,由于也是继承自BasePresenter类的所有在博客的编辑页面也有meta_description的编辑,但是由于为了方便,这部分放在了博客内容里,而meta_description属性没有编辑到。

** 问题的解决**

  • 由于要用到meta_description这个东西,所以可以在PostPresenter中定义一个meta_description方法,然后在方法里判断如果博客有编辑meta_description属性,则返回这个属性,否则返回编辑博客内容中的摘要部分.这时需要创建blog_presenter.rb在项目运行时初始化加载。
module Refinery
  module Blog
    class PostPresenter < BasePresenter
      # use truncated post.body as meta description if post.meta_description is blank
      def meta_description
        if @model.meta_description.blank?
          @model.body.partition('').first.gsub(/(\n|\r|\s)/, " ").truncate(150)
        else
          @model.meta_description
        end
      end
    end
  end
end

内置方法

其中refinerycms里面的post.rb也定义了平常用到的方法,比如博客的发布日期的排序,对应年份的博客都有了相对应的方法。需要我们去参考里面的源代码,我查看源码的方式是配置好pry,然后在console里直接用edit Refinery::Blog::Post的方式查看该类的定义。

refinerycms框架的小结

refinerycms也可以看作一个rails的项目来看待,其中需要修改到页面,需要把框架里对应页面的代码复制到对应的rails项目的目录下,直接修改,后面项目运行时会加载复制的那份,原生的会被覆盖。像博客的tag标签链接的跳转,在refinerycms是已经定义好的,我们只需要编写对应的模版,然后使用里面的变量即可(需要到refinerycms查看对应的controller).可以看成是一个集成了小功能的插件,可以被集成到rails项目中使用。但是refinerycms又是一个类似于rails的应用,里面有完整的mvc架构。

参考

Tags
refinerycms
联系我们