Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple filters support for layouts. #62

Open
0x1eef opened this issue Aug 12, 2022 · 3 comments
Open

Multiple filters support for layouts. #62

0x1eef opened this issue Aug 12, 2022 · 3 comments

Comments

@0x1eef
Copy link

0x1eef commented Aug 12, 2022

Hello !

I would like to first say, thank you for all your work on nanoc. I love it !
This issue is a feature request (maybe it's already possible, but I couldn't figure out how).

I would like to apply multiple filters to a layout - at the moment I could only figure out how to apply one filter (eg erb). The reason is that I would like to run the erb filter, followed by a custom filter that minifies the result of the erb filter.

The solution I came up with is this - but it is less than ideal because it implies using erb all the time, and I didn't see an easy way to avoid that.

Gist:

# lib/filters/minify_filter.rb
class MinifyFilter < Nanoc::Filters::ERB
  identifier :minify_erb
  type :text

  def run(content, params={})
    content = super(content, params)
    file = tmp_write(content)
    run_minify(file.path)
    File.read(file.path).tap { file.tap(&:unlink).close }
  end

  private

  def run_minify(path)
    system "minify", path, "--type", "html", "-o", path
  end

  def content_dir
    source = config[:data_sources].find { _1[:type] == "filesystem" }
    source[:content_dir] || File.join(Dir.getwd, "content")
  end

  def tmp_write(content)
    file = Tempfile.new('minify')
    file.write(content)
    file.tap(&:flush)
  end
end


# Rules
layout '**/*', :minify_erb
@denisdefreyne denisdefreyne transferred this issue from nanoc/nanoc Aug 21, 2022
@denisdefreyne
Copy link
Member

Hey there,

At the moment, the easiest (though a little repetitive) way to do this is to call :minify after the layout:

compile '/**/*.md' do
  filter :kramdown
  layout '/default.*'
  filter :minify
end

layout '/**/*.erb', :erb

The filter :minify is called separately after the layout call. (A compilation rule evaluates its steps in order, one after another.)

If two filters always need to happen in succession, then it might be worth having a way to explicitly combine filters. Something like this:

Nanoc::Filter.combine([:erb, :minify] => :my_erb)

(You’d still need to define your own :minify filter in this example.)

@0x1eef
Copy link
Author

0x1eef commented Aug 24, 2022

If two filters always need to happen in succession, then it might be worth having a way to explicitly combine filters. Something like this:

Nanoc::Filter.combine([:erb, :minify] => :my_erb)

That seems nice !

This is what I had imagined:

layout '**/*', [:erb, :minify]

I could see this working too:

layout '**/*', Nanoc::Filter.combine([:erb, :minify])

My only suggestion would be to not make a name of the combined filters required. I think it can be redundant (like in the examples above), and introduce a new filter name that is kind of strange (like :my_erb).

Thanks!

@0x1eef
Copy link
Author

0x1eef commented Jun 16, 2024

Hey 👋 I'm cleaning up my issue list. Not clear if this one is actionable or not. Please feel free to close if it is taking up space among legitimate issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants