Rails 如何在 Model 里生成页面的 html 文件

hlxwell · 2013年07月02日 · 最后由 hlxwell 回复于 2013年07月10日 · 5090 次阅读
本帖已被管理员设置为精华贴

举例:当创建了一篇文章后,希望把这篇文章的 show 页面 html 给存到指定目录。


需求是,当你创建文章以后,我要把整个页面的 css 和 html 全部打包成 zip。


解决篇

# 这个方法就能生成HTML了。当然我还不知道怎么吧@var传到view里去。
def to_html
  request = ActionDispatch::Request.new Hash.new
  # I am using Gon also.
  Gon.clear
  Gon::Request.instance_variable_set(:@request_id, request.object_id)
  Gon::Request.env = {}
  # Assign gon variables
  Gon.some_variables = self.some_variables

  view = ActionView::Base.new(views_path)
  view.controller = ArticlesController.new
  view.request = request
  text = view.render(
    :formats => ['json'],
    :template => 'articles/index',
    :layout => 'layouts/application',
    :locals => { :articles => @articles }
  )
end

private

def views_path
  @views_path ||= Rails.configuration.paths["app/views"]
end

def helpers
  @helpers ||= Rails.application.routes.url_helpers
end

def default_host
  @default_host ||= Rails.configuration.action_mailer.default_url_options[:host]
end

应要求,分享打包的代码

require 'zip/zip'
# Please run the method in background
def generate_offline_zip
  # ensure the folder was there.
  FileUtils.mkdir_p File.join(Rails.root, "tmp", "offline_zips")

  zip_path = File.join(Rails.root, "tmp", "offline_zips", "#{self.id.to_s}.zip")

  # Remove previous generated zip
  FileUtils.rm_rf zip_path

  Zip::ZipFile.open zip_path, Zip::ZipFile::CREATE do |zipfile|
    # Store js css
    zipfile.add "application.js", File.join(Rails.public_path, "assets", "application.js")
    zipfile.add "application.css", File.join(Rails.public_path, "assets", "application.css")
    zipfile.add "your_javascript.js", File.join(Rails.public_path, "assets", "your_javascript.js")
    # Store audio and images
    zipfile.add "audio.mp3", File.join(Rails.public_path, self.audio_path)
    zipfile.add "image.png", File.join(Rails.public_path, "assets", "image.png")
    # Store index.html
    zipfile.get_output_stream("index.html") { |f| f.puts self.to_html }
  end

  # move zip to public folder
  FileUtils.mkdir_p File.join(Rails.public_path, "zips") # make sure folder was there.
  FileUtils.mv zip_path, File.join(Rails.public_path, "zips", "#{self.id}.zip")
  true
rescue => e
  # error processing
  false
end

用 callback 跑个 curl ?

#1 楼 @blacktulip 如果这个页面需要登录的呢?

#2 楼 @hlxwell curl 可以登录的啊 不然就用 mechanize 爬一下?

用模版引擎直接调用啊

要么写 rack

#5 楼 @zgm 需求是,当你创建文章以后,我要把整个页面的 css 和 html 全部打包成 zip。 rack 是个点子但是这种情况就比较难了。

css 可以直接从文件系统得到,要 render 的 veiw 依赖 Rails 提供的一整套环境嘛? 如果不依赖 Rails 的话,有个插件叫做 Tile 你试试看。

先 thanks, 回头解决了再吧方案贴出来。 #8 楼 @lgn21st

弄个后台任务一个一个请求就可以啊 至于登陆不登陆问题设置一下 cookie 就行了

#10 楼 @hooopo #8 楼 @lgn21st #4 楼 @zgm #1 楼 @blacktulip

终于搞定了,其实可以用 Rails 里的方法自己弄。在帖子里更新了。 Thanks everybody

牛,掰,整个渲染 view 页面还真没干过。看来也可以根据这段代码用 html2pdf 自动化生成 pdf 了

#11 楼 @hlxwell 请问下这个方法能把页面里面引用的 css 文件之类的也抓出来打在包里不?

为什么不直接做缓存

#15 楼 @ihlayy  因为我要打包成 zip。

#14 楼 @blacktulip css 你得自己压缩的时候加到包里去。css 都是静态文件啊。

#17 楼 @hlxwell 把打包这块的代码也共享一下吧... 如果可以的话

#18 楼 @blacktulip 代码已分享,查看更新部分。

render_string 再抓回来不行吗?

#21 楼 @fenprace 你怎么在 model 里 render_to_string? 比如一篇文章编辑里,你希望重新压缩一个 zip。

#22 楼 @hlxwell 什么要求一定要在 Model 里实现?LZ 描述的需求貌似是要导出,在 Controller 里实现不就行了??

#23 楼 @fenprace 一个 controller 里不能多次 render,如果你要在一个 controller 里输出结果给用户又要输出页面去打包。你说怎么弄?

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