Rendering Error: RangeError: Maximum call stack size exceeded - docpad

I'm getting the following error generated from my default.html.eco layout when I attempt to render:
RangeError: Maximum call stack size exceeded
My docpad version is: v6.54.2, and the specific line causing it is this:
<%- #getBlock('scripts').add(['/vendor/foundation.min.js',
'/vendor/audiolib.js','/vendor/freqfinder.js','/vendor/modernizr.js']).toHTML() %>
If I remove this, I get a clean build.
Note that the styles block just above it renders just fine:
<%- #getBlock("styles").add(['/vendor/foundation.css']).toHTML() %>
So I decide to try truncating that list in the scripts block and it works:
<%- #getBlock("scripts").add(['/vendor/foundation.min.js']).toHTML() %>
Any ideas on how to work around this? I'll go file a bug if I'm not doing something wrong - new to docpad.

Do you have a line break in your code? It fails for me when I copy-paste from here to my layout file, but if I delete the line break between '/vendor/foundation.min.js', and '/vendor/audiolib.js' then it compiles as expected.
Alternatively, you could also a string of .add() commands like this:
<%- #getBlock('scripts').add('/vendor/foundation.min.js').add( '/vendor/audiolib.js').add('/vendor/freqfinder.js').add('/vendor/modernizr.js').toHTML() %>
That also comiples fine for me.
And a related note, in case anyone else comes across this error but doesn't have any line breaks: collection.add(null) now causes the same error message. So, if you're doing something like this:
<%- #getBlock("scripts").add( #getDocument().get('scripts') ).toHTML() %>
It will die if you don't have a scripts metadata field on every page.
The fix, however, is pretty simple:
<%- #getBlock("scripts").add( #getDocument().get('scripts') or [] ).toHTML() %>

Related

loop over hash in defined order in ruby template

I have a ruby template (.erb) that I want to iterate over a hash. It should produce the same output file each time the puppet agent runs.
What I currently have is the following. This is my template (part of rsyslog config if anyone is wondering):
<% log_files.each do |log_file, tag| -%>
# <%= log_file %>
$InputFileName <%= log_file %>
$InputFileTag <%= tag %>:
This template is rendered with a hash that looks like this:
log_files => {
'/root/apache_auth.local' => 'httpd',
'/root/install.log' => 'hugo',
},
(Not real logfiles). This works and produces the config file I want. The problem with this is that each time I call the puppet agent, the order of the log files in the hash is changed, so the config file gets rewritten, and subsequently the daemon gets restarted. The functionality stays the same, but I would rather not have the config file rewritten and rsyslog restarted each time the puppet agent runs.
Now I assume that this is unsolvable with hashes, as their nature is that they do not have a defined order. What other options do I have to achieve what I want?
Since the scriptlets inside an ERB template consist of Ruby code, this is essentially a Ruby question. The possible answers therefore depend on which version of Ruby is running underneath your Puppet catalog compiler. However, although there may be better alternatives in newer Ruby, this variation on your code will work in any Ruby supported by Puppet since Puppet 2.7:
<% #log_files.sort.each do |log_file, tag| -%>
# <%= log_file %>
$InputFileName <%= log_file %>
$InputFileTag <%= tag %>:
<% end -%>
The key here (no pun intended) is the sort.

Using Redcarpet Gem with .erb file

I am trying to pull up a markdown file from a database that I created. My server. rb file has the following:
get "/designers/:id" do
id = params[:id]
#content = conn.exec_params("SELECT * FROM articles_info WHERE id = $1",[id]).first
erb :raf
end
In that table is the following markdown information:
# **RAF SIMONS**
*THIS IS THE RAF SIMONS BIO* :blush:
*[Raf Link](http://rafsimons.com/)*
The .erb file works when I have plain text or the following in it:
<%= "#{#content["content"]}" %>
However it only prints the actual .md text as it is. So I have tried using Redcarpet to render the markdown file. The code is as follows in my .erb:
renderer = Redcarpet::Render::HTML.new
markdown = Redcarpet::Markdown.new(renderer)
<%= markdown.render(#content.content) %>
But I am getting the error:
ArgumentError at /designers/1
wrong number of arguments (0 for 1..3)
Which is stemming from the <%= line. I thought at first that the syntax was wrong, so I tried:
markdown.render <%= "#{#content["content"]} %>
However that did not change anything. I also tried adding in a method in the server.rb file, but that gave me more errors. I read through the entire documentation: https://github.com/vmg/redcarpet file but am not understanding where the error is coming from. Is it possible that I need extensions in order to make it work? I also tried:
markdown = Redcarpet::Markdown::new(renderer, extensions={})
But that didn't change anything. Not sure what else to try here! I know that it is tricky but I thought I had a handle on it and have now tried many different iterations and still am having trouble executing it. Any advice would be much appreciated!

.erb equivalent to the PHP $_GET["name"];

I have a page set up in PHP which pulls data from the URL and echos it in HTML. Is there a .erb Ruby equivalent to this?
<?php echo $_GET["name"];?>
Is this possible? Thanks!
In ERB, it looks like this:
<%= variable_name %>
If you want to perform some action without printing the result, you do this
<% #user.sign_up %>
Notice the difference being the =

Passing binding or arguments to ERB from the command line

I have been playing around with erb from the command line recently. I wanted to make a dirt simple erb template, for example the following:
<%- name = "Joe"; quality = "fantastic" -%>
Hello. My name is <%= name %>. I hope your day is <%= quality %>.
This works if I run
erb -T - thatfile.erb
what I want to do is to make name and quality be passable from command line arguments, so that I could do something like:
./thatfile.erb "Bill" "super"
from the bash prompt and do the same thing.
I am aware that I could write a ruby script that would just read that template in and then use ERB.new(File.read("thatfile.erb")).result(binding), or writing the template after an END and doing likewise, but I'm looking for a more lightweight approach if it exists, because I don't want to write two files for each erb script that I create for this purpose.
Alternatively, you can use a ruby script and load it in as a library.
# vars.rb
#hello = 'kirk'
# template.html.erb
<div><%= #hello %></div>
$ erb -r './vars' template.html.erb
Please note that Ruby 2.2 and newer provide a much nicer solution that was implemented according to this:
erb var1=val1 var2=val2 my-template.erb
I went with the BASH command-line shortcut for environmental variables.
Outside:
STUFF=foo,bar erb input.html.erb >output.html
Inside:
<%
stuff = ENV['STUFF'].split(',')
%>
After a few minutes e-searching I determined the other solutions are all variations on "write the erb wrapper command yourself." Could be wrong, but I ain't going back.
If you are using unix, try following:
$ cat 1.erb
Hello. My name is <%= name %>. I hope your day is <%= quality %>.
$ (echo '<% name="Joe"; quality="fantastic" %>' && cat 1.erb) | erb
Hello. My name is Joe. I hope your day is fantastic.

undocumented ERB syntax: <%=h ... %>

http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html lists a set of Recognized Tags - however, this list seems incomplete; for one thing it's missing the dash variant (<%- ... -%>, which suppresses line breaks IIRC).
Now I've come across another seemingly undocumented variant:
<%=h some_variable %>
<%= link_to h(some_variable) ... %>
Google wouldn't tell me what that was all about; can anyone point me to an explanation?
It's not an ERB syntax. It is <%= ... %> and inside it is calling the ERB::Util.hmethod
h here is just a regular method, in fact it's an alias for html_escape.
http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB/Util.html#M000868

Resources