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
"capturing" outside of :erb #1066
Comments
What would you think of allowing content_for(:head, 'some string') as an alternative to content_for(:head) { _erbout << 'some string' } ? That’d fit your use case, I believe. |
That would fit the use-case. As long as client code doesn't have to know implementation details of content_for(:head, 'string') and: content_for(:head) { 'string' } However, introduction of this new method signature is rather orthogonal to the loosening of the restriction that |
@sunshineco The only way content_for(:head) { _erbout << 'string' } i.e. <% content_for(:head) do %>string<% end %> The return value of the block passed to content_for(:head) { 'string' } A way to make this work outside of ERB could be to check whether or not |
An alternate idea (not sure what I think about it) would be to introduce a <% content_for(:head, from: :erb) %>string<% end %>
<% content_for(:head) %>string<% end %> To get it from the return value: content_for(:head, from: :return) { 'string' } … though I‘d rather infer the capturing method (erbout vs. return value) automatically. |
Right, I understand the implementation implications. My thinking all along has been that the implementation can be smart enough to figure out automatically (depending upon presence or absence of On the other hand, it may be too magical, and simply documenting that Anyhow, I don't feel too strongly one way or the other. I like the idea of |
I started working on a potential implementation in #1073. This one uses the format content_for(:head, 'string') |
Fixed in #1073. This’ll be part of Nanoc 4.6! |
Thanks for working on this, Denis. I look forward to being able to remove the ugly |
On my websites, I import several stand-alone HTML files verbatim into
content
as first-class nanoc items which should be incorporated into the website as proper pages, thus laid out and styled the same as the rest of the pages.For example, a source code project's
README.html
may be imported into the website as nanoc item/README.html
which is routed to/documentation/index.html
. Since these are full-blown HTML files, the enclosing<html>
and<body>
elements need to be stripped and the body content wrapped instead inside in a<div>
to become the item'scompiled_content
which is then laid-out via a normallayout
invocation in acompile
rule. This stripping of the unwanted HTML elements should be automated (I shouldn't have to do it by hand when importing the HTML file), thus seems a natural fit for a filter. For instance:In some cases, these foreign HTML files also have
<style>
and<script>
elements in<head>
which need to be incorporated into<head>
of the item laid out by nanoc. For example, inlayouts/default.html
:The
imported_html
filter looks something like this:The extracted
<style>
and<script>
elements need to be stored somewhere so that they can later be accessed by the layout; since filtering is happening at compile-time, they can't be stored as item attributes (which are frozen), thus storing them ascontent_for
seems appropriate.Unfortunately, this doesn't work.
content_for
expects to be called within the context of the:erb
filter and fails when called outside (say, from some other filter, such asimported_html
). Specifically,content_for
fails since there is no_erbout
. As a work-around, rather than callingcontent_for
directly, the filter instead callscapture_for
which is defined locally as:Although this works, it is ugly since it breaks the abstraction of nanoc's
capturing
helper by having special knowledge of its implementation.A cleaner solution would be for nanoc's
capturing
helper to be callable outside of an:erb
invocation, however, this is a somewhat esoteric use-case, thus it might not warrant a built-in solution from nanoc. On the other hand, it's not hard to imagine someone wanting to assign captured content to an item duringpreprocess
or within acompile
rule, so perhaps it's not so esoteric after all (although thepreprocess
case would require an API extension to allow specifying the item for which content is being stored). Also, I haven't been able to think of a good reason whycapturing
should be restricted only to:erb
; the restriction seems more an accident of implementation than an explicit decision.Other local (non-nanoc) solutions are certainly possible. For instance, the
imported_html
filter could, rather than invokingconent_for
itself, instead emit:erb
code along with the body content which would indirectly invokecontent_for
. For instance:with corresponding compilation rule:
which isn't too bad, though the extra indirection of having one filter write code for another filter is somewhat ugly, thus the question of whether this is something nanoc should support directly.
The text was updated successfully, but these errors were encountered: