Wicked_PDF templates is missing - ruby-on-rails

I installed wicked PDF and modified my controller :
def show
respond_to do |format|
format.pdf do
render :pdf => "file_name"
end
format.html
end
end
Here is how i link to the pdf : compte_contrat_path(c,:format=>'pdf')
It works for html (without the format) but fail for PDF with the following error :
Template is missing
Missing template contrats/show with {:locale=>[:fr], :formats=>[:pdf],
:handlers=>[:erb, :builder, :coffee, :arb]}. Searched in: *
"/home/sylario/ruby/place_de_marche/app/views" *
"/usr/local/rvm/gems/ruby-1.9.2-p136/gems/activeadmin-0.5.0/app/views"
* "/usr/local/rvm/gems/ruby-1.9.2-p136/gems/kaminari-0.14.1/app/views" * "/usr/local/rvm/gems/ruby-1.9.2-p136/gems/devise-2.2.0/app/views"
What am I doing wrong?

Thanks to henry I now know it was related to the format of the ERB.
I have found a way to reuse my html.erb files :
First i do the following in the controller
format.pdf do
render :pdf => "file.pdf", :template => 'contrats/show.html.erb'
end
Then when i use partials i call them like this :
render :partial => 'fullpath/toview.html.erb', :formats => [:html], :locals => { :mylocal=>#something }

For Rails 7, this is what works:
format.pdf do
render pdf: "file_name", template: "posts/show", formats: [:html]
end
Notice that template no longer have .html.erb and don't forget to include 'formats'.

Related

Rails looking for template for JSON requests

In my routes.rb I have:
resources :workouts
In my workouts controller I have:
def show
respond_to do |format|
format.html
format.json { render :json => "Success" }
end
end
But when I go to /workouts/1.json, I receive the following:
Template is missing
Missing template workouts/show, application/show with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :coffee]}. Searched in: * "/home/rails/app/views"
Which appears to show that the format is what it should be but it's still searching for a view. This same code functions in other controllers with identical setups just fine. Also, going to /workouts/1 for the html view seems to work just fine, though it also renders the html view properly when the format.html is removed.
Looks at the source code of render
elsif options.include?(:json)
json = options[:json]
json = ActiveSupport::JSON.encode(json) unless json.is_a?(String)
json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
response.content_type ||= Mime::JSON
render_for_text(json, options[:status])
Pay attention to the third line. If the value of :json is a string, render won't call to_json automatically for this value.
So the value remains as string and render will go on to search template.
To fix, supply a valid hash even for trying purpose.
format.json { render :json => {:message => "Success"} }
You would try with /workouts.json

If there is no need to response in remote form how to handle it on Rails 3?

If there is no need to response in remote form how to handle it?
the error is
ActionView::MissingTemplate (Missing template carts/search_book_by_sn, application/search_book_by_sn with {:locale=>[:en], :formats=>[:js, :html], :handlers=>[:erb, :builder, :coffee, :haml]}. Searched in:
The code in my controller.
Because the
if session[:loaded_books].include? #book.id
is a condition for false-result, so I don't want to execute any Javascript. Just keep it as same as origin
respond_to do |format|
# format.js
if session[:loaded_books].include? #book.id
format.js
else
ap("Add into Array")
session[:loaded_books] << #book.id
ap(session[:loaded_books])
format.js { render :action => 'add_to_cart'}
end
end
Thanks in advance
If you don't want to send any response or render any view then the write in action
render :nothing => true
respond_to do |format|
# format.js
if session[:loaded_books].include? #book.id
format.js {render :nothing => true } # this might help
else
ap("Add into Array")
session[:loaded_books] << #book.id
ap(session[:loaded_books])
format.js { render :action => 'add_to_cart'}
end
end
simply do render :nothing => true in your controller

How can I render an HTML view while constructing a JSON response in Rails?

I have a controller method that returns JSON. But sometimes part of that JSON object should include a rendered, serialized HTML view. So my controller method has a line like this:
html = render_to_string :partial => 'foo/bar'
# ...
render json: {x: 'y', html: html}
But that fails because Rails is only looking for JSON views!
ActionView::MissingTemplate (Missing partial foo/bar with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :coffee, :slim, :haml]}. […]
How can I solve this?
Update: I have gotten one "level" of layout to render_to_string as html using the below syntax, but the same error persists when that layout renders its own partials!
html = render_to_string :partial => "foo/bar.html.haml"
Surely there’s a solution here, right?
Update 2: render_to_string :action => 'method_in_this_controller' seems to be doing the trick.
Repeating Yanhao's answer because I ran into this exact problem and its what worked for me.
try:
html = render_to_string :partial => 'foo/bar', :formats=>[:html]
I am writing something like that in my action:
def show
...
respond_to do |format|
format.js { render :json => data }
end
end
May be it will help you.
Are you sure you have a file 'apps/views/foo/_bar.*'? I was able to render HTML as a JSON parameter with How do I render a partial to a string?
respond_to do |format|
format.html { redirect_to post_path(post) }
format.js {
render json: {
error: flash[:error],
content: (render_to_string partial: '/comments/comment', locals: {comment: comment}, layout: false )
}
}
end

"Template is missing" when rendering Liquid template

I'm trying to render a liquid template that is stored in the database.
Here is my 'show' action in the controller:
def show
#organization = Organization.find_by_subdomain(request.subdomain)
#template = Liquid::Template.parse(Template.find(#organization.current_template).body)
#page = #organization.pages.find(params[:id])
respond_to do |format|
format.html { render #template.render('page' => #page), :template => false}
format.json { render json: #page }
end
end
However, when I visit the page, I get a "Template is Missing" exception with the following error (note that "testing testing" is the body attribute of the page object, which is currently the only thing being rendered in the template):
Missing template /testing testing with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee, :haml]}.
Searched in: * "/Users/ashercohen/Documents/Rails/Vocalem-Rails/app/views"
* "/Users/ashercohen/.rvm/gems/ruby-1.9.3-p194/gems/twitter-bootstrap-rails-2.1.1/app/views"
* "/Users/ashercohen/.rvm/gems/ruby-1.9.3-p194/gems/devise-2.1.2/app/views"
Why is it trying to find another template, when I've specifically pass the :template => false argument? Is there something I'm missing here? I'm trying to bypass using any template files, as it seems like they shouldn't be needed here (though am not strongly opposed if I am wrong).
Because render almost always takes a filename, while #template.render('page' => #page) contains the plain html. You should invoke render like this:
render :text => #template.render('page' => #page), :content_type => :html

render_to_string does not find partials (PDFKit controller response)

Ruby 1.8.7, Rails 3.0.4, PDFKit 0.5.0
I'm trying to create a PDF with PDFKit without using the middleware so I can disable javascript (there's an accordion action in there that hides a lot of info that should be on the PDF). However, whenever I try, it fails because it says the partials in my view (show.html.erb) are missing:
Missing partial programs/details with {:locale=>[:en, :en], :formats=>[:pdf], :handlers=>[:erb, :rjs, :builder, :rhtml, :rxml]}
If I remove the references to the partials, it works fine. I've also tried putting the partials in the same directory with show.html.erb to no avail. Here is the code in my controller's show action:
respond_to do |format|
format.html # show.html.erb
format.pdf {
html = render_to_string(:template => "show.html.erb")
kit = PDFKit.new(html, :disable_javascript => true )
send_data(kit.to_pdf, :filename => "test_pdf", :type => "application/pdf", :disposition => 'attachment')
}
end
Is there any way to do this and keep the partials?
EDIT: for now I've done this:
# config/initializers/pdfkit.rb
PDFKit.configure do |config|
config.default_options = {
:page_size => 'Legal',
:print_media_type => true,
:disable_javascript => true
}
end
This has the disadvantage of turning off javascript for every PDF I generate, but it'll do for now. Any answers on the original question of getting the partials to work still with render_to_string still appreciated.
I was running into this issue this morning and came across your question while looking for a solution.
Controller extract:
respond_to do |format|
format.html
format.pdf {
html = render_to_string(:layout => false , :action => "constitution.pdf.haml")
kit = PDFKit.new(html)
kit.stylesheets << "#{Rails.root}/public/stylesheets/pdf.css"
send_data(kit.to_pdf, :filename => "#{#organisation_name} Constitution.pdf",
:type => 'application/pdf', :disposition => 'inline')
return
}
end
constitution.pdf.haml extract:
=render :partial => 'shared/constitution'
Error:
Missing partial shared/constitution with {:locale=>[:en, :e ...
After a while banging my head against a wall, I had a guess and changed constitution.pdf.haml to:
=render :partial => 'shared/constitution.html.haml'
I only know a tiny amount about Rails. Could it really be that (unlike my normal Haml views), PDFKit requires the file extension? That's fixed it for me!
You can also set :formats for render_to_string to prevent having to change your partial names.
html = render_to_string(:layout => false , :action => "show", :formats => :html)
This forces html, instead of pdf, format for the remained of the view rendering. Allowing you to use the same views/partials without change for HTML and PDF responses.
You should specify full path to your template I think:
html = render_to_string(:template => "my_view_folder_name/show.html.erb")

Resources