Class: Sghtmltopdf::Renderer

Inherits:
Object
  • Object
show all
Defined in:
lib/sghtmltopdf/renderer.rb

Overview

render pdf: "invoice"のオプションを、

  • Railsのビュー描画(render_to_string)へ渡すもの
  • レスポンスの組み立て(send_data)へ渡すもの
  • PDF変換(Sghtmltopdf.render)へ渡すもの

の3つに振り分ける。 Railsに依存しないpure Rubyのクラスなので、Rails無しでも単体テストできる。

Constant Summary collapse

RAILS_RENDER_KEYS =

render_to_stringへそのまま渡すキー。

%i[
  action assigns body collection file formats handlers html inline layout
  locals object partial plain prefixes template variants
].freeze
RESPONSE_KEYS =

レスポンスの組み立てに使うキー(send_dataへ渡す)。

%i[disposition filename status].freeze
RENDERER_KEYS =

レンダラ自身が解釈するキー(PDFにせずHTMLのまま返すデバッグ用)。

%i[show_as_html].freeze
PDF_CONTENT_TYPE =
"application/pdf"
HTML_CONTENT_TYPE =
"text/html"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, options = {}, default_name: nil) ⇒ Renderer

Returns a new instance of Renderer.

Parameters:

  • name (String, Symbol, nil)

    pdf:に渡された値(ファイル名の素)

  • options (Hash) (defaults to: {})

    renderに渡されたその他のオプション

  • default_name (String, nil) (defaults to: nil)

    nameが空のときのファイル名 (コントローラのaction_nameを想定)



34
35
36
37
# File 'lib/sghtmltopdf/renderer.rb', line 34

def initialize(name, options = {}, default_name: nil)
  @name = blank?(name) ? (default_name || "document").to_s : name.to_s
  @options = options.to_h { |key, value| [key.to_sym, value] }
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



28
29
30
# File 'lib/sghtmltopdf/renderer.rb', line 28

def name
  @name
end

#optionsObject (readonly)

Returns the value of attribute options.



28
29
30
# File 'lib/sghtmltopdf/renderer.rb', line 28

def options
  @options
end

Class Method Details

.register!Object

ActionController::Renderers.add(:pdf)でレンダラを登録する。 RailtieのAction Controller読み込みフック(on_load)から呼ぶ。



41
42
43
44
45
46
47
# File 'lib/sghtmltopdf/renderer.rb', line 41

def self.register!
  ::ActionController::Renderers.add(:pdf) do |name, options|
    renderer = ::Sghtmltopdf::Renderer.new(name, options, default_name: action_name)
    html = render_to_string(**renderer.render_options)
    send_data(renderer.body_for(html), **renderer.send_data_options)
  end
end

Instance Method Details

#body_for(html) ⇒ Object

描画したHTMLをレスポンスの本文へ変換する。



61
62
63
# File 'lib/sghtmltopdf/renderer.rb', line 61

def body_for(html)
  show_as_html? ? html : Sghtmltopdf.render(html, **convert_options)
end

#content_typeObject



72
73
74
# File 'lib/sghtmltopdf/renderer.rb', line 72

def content_type
  show_as_html? ? HTML_CONTENT_TYPE : PDF_CONTENT_TYPE
end

#convert_optionsObject

PDF変換に使うオプション。



55
56
57
58
# File 'lib/sghtmltopdf/renderer.rb', line 55

def convert_options
  known = RAILS_RENDER_KEYS + RESPONSE_KEYS + RENDERER_KEYS
  options.reject { |key, _| known.include?(key) }
end

#dispositionObject

wicked_pdfと同じく既定はinline(ブラウザ内で開く)。



83
84
85
# File 'lib/sghtmltopdf/renderer.rb', line 83

def disposition
  blank?(options[:disposition]) ? "inline" : options[:disposition].to_s
end

#filenameObject

filename: "x.pdf" > pdf: "x" の順。拡張子は二重に付けない。



77
78
79
80
# File 'lib/sghtmltopdf/renderer.rb', line 77

def filename
  base = blank?(options[:filename]) ? name : options[:filename].to_s
  base.downcase.end_with?(".pdf") ? base : "#{base}.pdf"
end

#render_optionsObject

ビューの描画に使うオプション。



50
51
52
# File 'lib/sghtmltopdf/renderer.rb', line 50

def render_options
  options.select { |key, _| RAILS_RENDER_KEYS.include?(key) }
end

#send_data_optionsObject



65
66
67
68
69
70
# File 'lib/sghtmltopdf/renderer.rb', line 65

def send_data_options
  opts = {type: content_type, disposition: disposition}
  opts[:filename] = filename unless show_as_html?
  opts[:status] = options[:status] if options.key?(:status)
  opts
end

#show_as_html?Boolean

wicked_pdfのshow_as_html相当。PDFにせずHTMLをそのまま返すので、 ブラウザの開発者ツールでレイアウトを確認できる。

Returns:

  • (Boolean)


89
90
91
92
# File 'lib/sghtmltopdf/renderer.rb', line 89

def show_as_html?
  value = options[:show_as_html]
  !(value.nil? || value == false || value == "false")
end