Skip to content

Instantly share code, notes, and snippets.

@NV
Created September 26, 2012 14:19
Show Gist options
  • Save NV/3788329 to your computer and use it in GitHub Desktop.
Save NV/3788329 to your computer and use it in GitHub Desktop.
Jekyll plugin for creating an alternative view (e.g. print view) for a post
require 'delegate'
module Jekyll
class PrintablePage < DelegateClass(Page)
def initialize(page)
@real_page = page
@dir = page.dir
#@base = page.base
# page.base is undefined, but it doesn’t seem to be used anyway
@name = page.name
@site = page.site
super(@real_page)
self.data = @real_page.data.clone
self.data['layout'] = @site.config['printable_layout'] || 'printable'
@printable_html = @site.config['printable_html'] || 'printable.html'
end
def destination(page)
page_path = super(page)
page_path.sub('index.html', @printable_html)
end
def write(dest)
# This is a copy/paste of the original Jekyll’s method.
# I don’t know how to avoid it, I’m just a Ruby newbie.
path = destination(dest)
FileUtils.mkdir_p(File.dirname(path))
File.open(path, 'w') do |f|
f.write(self.output)
end
end
end
class Site
alias orig_write write
def write
orig_write
self.posts.each do |page|
printable_page = PrintablePage.new(page)
printable_page.render(self.layouts, site_payload)
printable_page.write(self.dest)
end
end
end
end
@oleg-nenashev
Copy link

oleg-nenashev commented Jun 2, 2024

I confirm this code still works with Jekyll 4.3.x, with some adaptations.
My current code that also uses a separate directory so that it can be easily excluded from Jekyll Watcher:

##
# Credits: Nikita Vasilyev, https://gist.github.com/NV
# Source: https://gist.github.com/NV/3788329
# The version was highly adapted for the new Jekyll versions
##
require 'delegate'

module Jekyll
  class PrintablePageGenerator < Jekyll::Generator
    safe true

    def generate(site)
      collection = PrintableCollection.new(site)
      site.posts.docs.each do |page|
        printable_page = PrintablePage.new(page, collection)
        Jekyll.logger.info "Generated: ", printable_page.name + " - " + printable_page.path
        Jekyll.logger.warn "TEST - " + printable_page.name + " - URL: " + printable_page.url
        site.pages << printable_page
      end
    end
  end

  class PrintablePage < DelegateClass(Jekyll::Page)

    attr_accessor :output, :content
    attr_accessor :id, :name, :url
    attr_accessor :path, :relative_path
    attr_accessor :renderer, :data

    def initialize(page, collection)
      @real_page = page
      @site = @real_page.site
      
      super(@real_page)

      @original_path = page.relative_path
      @original_dir = File.dirname(page.relative_path)
      @original_name = File.basename(page.relative_path, ".*")
      @name = @original_name + "-raw"
      @id = @name
      @url =  "/raw/" + @original_name + "/raw.html"
      @collection = collection
      
      @relative_path = relativeDestination()
      @dir = File.dirname(relativeDestination())
      @base = nil
      @path = @site.in_source_dir(@base, @dir, @name)
      
      documentData = Hash.new()
      documentData[:site] = @site
      documentData[:collection] = collection
      @document = self

      @renderer = PrintableRenderer.new(site, self)
      @content = @real_page.content.clone
      @output = "test"

      self.data = @real_page.data.clone
      self.data['layout'] = @site.config['printable_layout'] || 'printable'
      self.data['slug'] = self.url()
    end

    def relativeDestination()
      path = @original_dir + "/../raw/" + @original_name + '/raw.html'
      path
    end

    def destination(base_directory)
      @destination = site.in_dest_dir(base_directory, self.relativeDestination)
      @destination
    end

    def html?()
      true
    end

    def file_exists?()
      true
    end

    def write(base_dir)
      destination = destination(base_dir)
      FileUtils.mkdir_p(File.dirname(destination))
      Jekyll.logger.info "Writing:", destination
      
      File.open(destination, 'w') do |f|
        f.write(self.output)
      end
    end
  end

  class PrintableRenderer < Renderer
    def initialize(site, document, site_payload = nil)
      super(site, document, site_payload)
    end

    def render_layout(output, layout, info)
      payload["content"] = output
      payload["layout"]  = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
      
      res = render_liquid(
        layout.content,
        payload,
        info,
        layout.path
      )
      Jekyll.logger.info "Rendered Layout:", @document.id + " - " + @document.path
      res
    end

    def assign_pages!
      payload["page"] = document.to_liquid
      payload["paginator"] = nil
    end
  end
  
  class PrintableDocument < Jekyll::Collection
    def initialize(path, metadata)
      super(path, metadata)
    end
  end
 

  class PrintableCollection < Jekyll::Collection
    def initialize(site)
      super(site, "printable")
    end
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment