From c0ebef2b7523aebcf46095fc79d3f2afc5e7161b Mon Sep 17 00:00:00 2001 From: Brad Gessler Date: Sun, 25 Feb 2024 11:53:56 -0800 Subject: [PATCH] Add around_template and text rendering --- README.md | 4 ++- lib/phlex/pdf.rb | 55 ++++++++++++++++++++++++++++++++------ spec/phlex/pdf_spec.rb | 60 +++++++++++++++++++++++++++++++----------- 3 files changed, 95 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index a963b7c..1f861d4 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ If bundler is not being used to manage dependencies, install the gem by executin ## Usage +`Phlex::PDF` is a thin wrapper around `Prawn::View`, so you'll want to become familiar with [PrawnPDF](http://prawnpdf.org/), particularly the [PrawnPDF Manual](https://prawnpdf.org/manual.pdf). + ```ruby require "phlex/pdf" @@ -44,7 +46,7 @@ class NoticeComponent < ApplicationComponent end end -NoticeComponent.pdf.render_file "poof.pdf" +NoticeComponent.render_file "hello.pdf" ``` ## Development diff --git a/lib/phlex/pdf.rb b/lib/phlex/pdf.rb index 23a71e7..a62a270 100644 --- a/lib/phlex/pdf.rb +++ b/lib/phlex/pdf.rb @@ -12,19 +12,58 @@ class Error < StandardError; end def call(document, &block) @document = document - before_template if respond_to?(:before_template) - view_template(&block) - after_template if respond_to?(:after_template) + around_template do + view_template(&block) + end end - def render(component, &block) - component.call(@document, &block) + # @abstract Override this method to hook in around a template render. You can do things before and after calling `super` to render the template. You should always call `super` so that callbacks can be added at different layers of the inheritance tree. + # @return [nil] + def around_template + before_template + yield + after_template nil end - def self.document(document = Prawn::Document.new) - new.call(document) - document + # @abstract Override this method to hook in right before a template is rendered. Please remember to call `super` so that callbacks can be added at different layers of the inheritance tree. + # @return [nil] + def before_template + nil + end + + # @abstract Override this method to hook in right after a template is rendered. Please remember to call `super` so that callbacks can be added at different layers of the inheritance tree. + # @return [nil] + def after_template + nil + end + + def render(renderable, &block) + case renderable + when String + @document.text renderable + when Phlex::PDF + renderable.call(@document, &block) + else + raise ArgumentError, "You can't render a #{renderable.inspect}." + end + + nil + end + + class << self + def document(document = Prawn::Document.new) + new.call(document) + document + end + + def render(...) + document.render(...) + end + + def render_file(...) + document.render_file(...) + end end end end diff --git a/spec/phlex/pdf_spec.rb b/spec/phlex/pdf_spec.rb index a88d9ad..e7be840 100644 --- a/spec/phlex/pdf_spec.rb +++ b/spec/phlex/pdf_spec.rb @@ -1,21 +1,51 @@ # frozen_string_literal: true -RSpec.describe Phlex::Pdf do - it "generates a PDF" do - class ApplicationComponent < Phlex::PDF - def before_template - text "Before #{self.class.name}" - end - - def view_template - text self.class.name - end - - def after_template - text "After #{self.class.name}" - end +require "phlex/pdf" + +class ApplicationComponent < Phlex::PDF + def before_template + text "Before #{self.class.name}" + end + + def view_template + text self.class.name + end + + def after_template + text "After #{self.class.name}" + end +end + +class HeaderComponent < ApplicationComponent + def view_template + text "Header" + end +end + +class FooterComponent < ApplicationComponent + def view_template + text "Footer" + end +end + +class BodyComponent < ApplicationComponent + def view_template + render "Body" + end +end + +class PageComponent < ApplicationComponent + def view_template + render HeaderComponent.new + render BodyComponent.new do + yield end + render FooterComponent.new + end +end - ApplicationComponent.document.render +RSpec.describe Phlex::PDF do + it "generates a PDF" do + PageComponent.render_file "poof.pdf" end end