Rails get dump of rendered view - ruby-on-rails

How can i include render response of a view inside another , but dumped.
like i am currently using:
css: "<%= render :partial => "myurl/blah", :formats=> [:css], :layout => false %>",
( in a rendered js file, where i am creating a json object and including various other files too.. )
The response here is like this :
css: "#utilities {width: 800px;}
#utilities p,
#utilities ul {margin-bottom: 1em;}
#utilities_scroll {height:500px; padding:0 10px 0 10px; overflow:scroll;}
#utilities_scroll_inner {width: 733px;}
#utilities-search-form {margin-top: 20px;} .. ."
However i want dump of it like this :
css: "#utilities {width: 800px;}\n#utilities p,\n#utilities ul {margin-bottom: .. "
EDIT:
In response to:
css : <%= eval("render :partial => 'myurl/blah', :formats=> [:css], :layout => false").dump %>
It is dumping the html but slightly incorrect way,
See in rails console :
a = "fdjasdlkfs 32$#%$#^$%^<>tv5$ ;'" # => "fdjasdlkfs 32$#%$#^$%^<>tv5$ ;'"
a.dump #=> "\"fdjasdlkfs 32$#%$#^$%^<>tv5$ ;'\""
That would be correct way but , in html with the line i'm including , the response is as :
(if i have in myurl/blah.css file as : "fdjasdlkfs 32$#%$#^$%^<>tv5$ ;'"
The result is
css : "\"fdjasdlkfs 32$#%$#^$%^<>tv5$ ;'\"\n"
see the difference as < > " are transformed very differently in both cases..( i needed it as per first format"

Use eval . I never tried this before but it would work .
Try :
css : <%= eval("render :partial => 'myurl/blah', :formats=> [:css], :layout => false") %>

Thanks to Vik for efforts... But after long hours of search i ended up as :
css : <%= JSON.dump(render :partial => "abc/url", :formats=> [:css], :layout => false).html_safe %>
css: <%= eval("render :partial => 'blah/blah', :formats=> [:css], :layout => false").dump.html_safe%>,
css: <%= eval("render :partial => 'blah/blah', :formats=> [:css], :layout => false").to_json.html_safe%>,
as solution for the problem....
I have just started up on Ruby,rails and find strange there is no proper documentation regarding all these small things...hope this helps someone...
however in my case i ended up using for my solution as :
( a little diff from question )
in controller :
#cssrender = JSON.dump(render_to_string(:file => "blah/blah", :layout => false , :formats =>[:css]))
and in view just css :<%=#cssrender.html_safe%>

Related

Rails 4, How to add an s3 image to wicked pdf

In rails 4, I am using wicked_pdf gem for .pdf file download. I have to add an image inside this pdf, right now image is rendering through wicked_pdf_image_tag in development but in test environment image(s3) is not rendering.
Used Gems are,
gem 'wicked_pdf', '1.0.3'
gem 'wkhtmltopdf-binary', '0.9.9.3'
In initializers,
class WickedPdf
wkhtmltopdf_path = Rails.env.production? ? "#{Rails.root}/bin/wkhtmltopdf-amd64" : "#{Rails.root}/bin/wkhtmltopdf-amd64"
WICKED_PDF = {
:exe_path => wkhtmltopdf_path,
:wkhtmltopdf => wkhtmltopdf_path
}
end
In controller,
respond_to do |format|
format.html {
render :pdf => "sample",
:margin => {:top => 10, :bottom => 10, :left => 10, :right => 10},
:orientation => 'Portrait', # default , Landscape,
:no_background => true
}
end
In views, I have tried to load through
<%= Rails.env.development? ? wicked_pdf_image_tag("img/logo.png") : wicked_pdf_image_tag("#{Rails.root}/public/assets/img/logo.png") %>
<%= Rails.env.development? ? wicked_pdf_image_tag("img/logo.png") : wicked_pdf_image_tag("#{Rails.root}/assets/img/logo.png") %>
<%= image_tag(ActionController::Base.helpers.asset_path('img/logo.png')) %>
How can I load s3 image in pdf file?
You can put the image in a s3 bucket and make it public. After that try it like below. If you use the below code no need to use separate syntax for different environments, it will works for all .Hope it works.
<%= wicked_pdf_image_tag('//s3.amazonaws.com/bucket_name/image.png') %>
I have worked on the similar functionality but using PDFKit gem. But I think rendering logic will be almost similar.
Below is the code where I rendered my partial in controller
def print_batch
batch = Batch.find(params[:id])
respond_to do |format|
format.pdf {
html = render_to_string("_batch",:formats => [:html], layout: false , locals: { batch: batch })
Rails.logger.debug(html.inspect)
kit = PDFKit.new(html)
send_data(kit.to_pdf, :filename => "file_name_#{batch.id}.pdf", :type => 'application/pdf') and return
}
format.html
format.json { render json: {id: batch.id, processed: batch.processed?} }
end
end
In _batch.html.haml. You can see I have used person.s3_logo for rendering the pdf image.
- logo_image_pdf = person.logo.present? ? person.s3_logo : default_credit_logo
- logo_image_html = person.logo.present? ? image_path(Person.logo.thumb('100x100').url) : image_path('default_credit_logo.png')
- logo_image = params[:format] == 'pdf' ? logo_image_pdf : logo_image_html
.bucks
%img.logo{src: logo_image }
In Person.rb model. Anyway we cannot directly render image in PDF file directly from s3. So any gem will first download it in /tmp folder and render it. This is how I have done it in my model file.
def s3_logo
file = open(self.logo.remote_url)
file.path if file
end

Wicked_pdf page width in multipage pdf

Cheers! I'm using wicked_pdf to generate pdf docs from views:
pdf = WickedPdf.new.pdf_from_string(
render_to_string(
:layout => "pdf_report.haml",
:handlers => [:haml],
:formats => [:pdf, :haml],
:orientation => 'Landscape',
:encoding => "utf8",
:page_width => '2000',
:dpi => '300'
)
)
It's all ok, if pdf has one page:
But if pdf doc has more than one page, then width of the page is broken:
I wasn't able to reproduce your "only has one page" scenario with the code you posted, however there is a problem with the options you are passing. They aren't even getting to wkhtmltopdf, so it is probably deciding for you what kind of options to use.
render_to_string will silently discard any options it doesn't understand, but is not part of wicked_pdf.
pdf_from_string takes two params, the first being the string to pdf-ify, the second is a hash of pdf options from the README.
I've added your issue to the wicked_pdf_issues project here to reproduce and debug it:
https://github.com/unixmonkey/wicked_pdf_issues/commit/b722e8a06c42e1f2bcbb98281915d1e94b4fe2c9
You should get the results you are looking for by changing your code to something like this:
string = render_to_string(
template: 'pages/issue_330',
formats: [:pdf],
handlers: [:erb]
)
options = {
orientation: 'Landscape',
page_width: '2000',
dpi: '300'
}
pdf = WickedPdf.new.pdf_from_string(string, options)

wicked_pdf is not rendering header

render :pdf => "file_name",
:layout => 'pdf.html.erb',
:template => 'transactions/show.pdf.erb',
:wkhtmltopdf => WICKED_PDF_BIN,
:show_as_html => true,
:layout => 'pdf.html.erb',
:header => {:html => { :template => 'shared/header.pdf.erb'}}
PDF is generated fine, unfortunately I do not see the header. I can stick the header in the main layout and it works fine too. It seems to me that the header line above is not being processed. The filename 'header.pdf.erb' does not seem to matter. I can point it to a file that does not exist and it throws no error.
This is Mac OS, Rails 3.2.1, ruby 1.9
You may want to simply render the template as a string and assign it to the header's content. Try this out:
header: {
content: render_to_string(template: 'header.pdf.haml')
}
It works well for me.

Apotomo: How do you render a state/view that's in HTML format from another view that's in another format?

For reasons beyond this problem, I need to respond with JSON when creating an image:
<%=
raw({
...
:url => #image.url(:width => #width, :height => #height),
:edit_link => render({:state => :image_edit_table_cell, :template_format => :html}, #image),
# btw, I've also tried passing :format => :html
:delete_link => link_to_destroy_image(#image, :remote => true, :path => url_for_event(:destroy, :image_id => #image)),
...
}.to_json)
%>
However, in that JSON, I want to include some pretty fancy HTML. To include that, I render a state/view (as you can see in the :edit_link portion). This is the image_edit_table_cell.html.haml view of the widget:
= link_to_edit_image #image, :remote => true
# ... doesn't really matter - as long as you know this is html.haml
However, when I create an image, and the JSON is rendered, I get a Missing template error:
ActionView::Template::Error (Missing template cell/rails/image_edit_table_cell with {:handlers=>[:builder, :rjs, :rhtml, :erb, :haml, :rxml], :locale=>[:en, :en], :formats=>[:json]} in view paths "/home/ramon/source/unstilted/app/widgets", "/home/ramon/source/unstilted/app/widgets/layouts" and possible paths image/table/image_edit_table_cellapplication/image_edit_table_cellapotomo/widget/image_edit_table_cellcell/rails/image_edit_table_cell):
6: :caption => #image.caption || "",
7: :text_tag => #image.text_tag(:width => #width, :height => #height),
8: :url => #image.url(:width => #width, :height => #height),
9: :edit_link => render({:state => :image_edit_table_cell, :template_format => :html}, #image),
10: :delete_link => link_to_destroy_image(#image, :remote => true, :path => url_for_event(:destroy, :image_id => #image)),
11: :success => true
12: }.to_json)
app/widgets/image/table_widget.rb:37:in `image_edit_table_cell'
app/widgets/image/table/new_image.json.erb:9:in `_app_widgets_image_table_new_image_json_erb___457172591_99648970_0'
app/widgets/image/table_widget.rb:16:in `add_image'
app/widgets/image/uploader_widget.rb:22:in `upload'
It seems like the problem is that since I'm rendering it from a JSON file, it doesn't know to look for an HTML file (thus the format it's looking for is json. That's why you see the :template_file => :html option (I got that from here) in the first block of code above.
I'm using these gems:
'rails', '3.0.10'
'cells', '3.6.2'
'apotomo', "1.1.2"
Apparently, this is a Rails issue, not an Apotomo issue. This answer did it for me! Key is setting the format in your view file before you render your html view:
<% self.formats = ["html"] %>

Multiple files upload with Rails 3 and paperclip on heroku

I need an interface on my Rails 3 app to upload multiple files to Amazon S3 (because i'm on heroku), possibly with progress bars.
I've easily managed how to set up paperclip and upload single files, but i'm really lost now on how to go ahead.
Please can you give me some advices? It's 2 days i'm searching across all the internet, but i can't find a working solution
** EDIT **
I really can't understand... I'm going mad 'cause I'm losing too many hours on this... please help me.
If I try to open the example app cited by Johnny I only get this (and in my app it is the same):
Where is the UI?
Is there something wrong on my browser?
** EDIT 2 **
Here on GitHub you can find my testapp... please can you explain me why the damn upload UI is not showing up? Thanks!
** EDIT 3 **
Thank you very much Johnny, i wasn't aware of the fact that jquery and prototype can't live together.
Now the plugin is showing up correctly, but as a try to upload something it creates a new "upload" record, but its attachment field is blank, and the files are not on s3.
This is what the console is saying:
Started POST "/uploads" for 127.0.0.1 at 2011-06-27 16:17:22 +0200
Processing by UploadsController#create as JSON
Parameters: {"utf8"=>"✓", "authenticity_token"=>"GesRBTiZR1f2LV/bAeAdxWqF++gxcDJw4pPGStYGsH8=", "upload"=>{"attachment"=>[#<ActionDispatch::Http::UploadedFile:0x000001032834b8 #original_filename="animal-tiger-66550.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"upload[attachment][]\"; filename=\"animal-tiger-66550.jpg\"\r\nContent-Type: image/jpeg\r\n", #tempfile=#<File:/var/folders/Qj/QjEqvUUNGTmuki5SXOaaG++++TI/-Tmp-/RackMultipart20110627-1818-1syiex9>>]}}
AREL (0.5ms) INSERT INTO "uploads" ("attachment", "created_at", "updated_at", "attachment_file_name", "attachment_content_type", "attachment_file_size", "attachment_updated_at") VALUES (NULL, '2011-06-27 14:17:23.049136', '2011-06-27 14:17:23.049136', NULL, NULL, NULL, NULL)
[paperclip] Saving attachments.
Completed 200 OK in 64ms (Views: 4.2ms | ActiveRecord: 0.7ms)
You can look at jQuery-File-Upload. Demo here and rails 3/Paperclip setup here.
Edit: As #apneadiving mentioned, the library has been updated to version 5. The script you have is for verison 4. You should try modifying this to work with PaperClip. Copy-pasting the majority of the example code into my app (with a few modifications) worked for me:
#app/public/javascripts/application.js
$(function () {
// Initialize the jQuery File Upload widget:
$('#fileupload').fileupload();
// Load existing files:
$.getJSON($('#fileupload form').prop('action'), function (files) {
var fu = $('#fileupload').data('fileupload');
fu._adjustMaxNumberOfFiles(-files.length);
fu._renderDownload(files)
.appendTo($('#fileupload .files'))
.fadeIn(function () {
// Fix for IE7 and lower:
$(this).show();
});
});
// Open download dialogs via iframes,
// to prevent aborting current uploads:
$('#fileupload .files a:not([target^=_blank])').live('click', function (e) {
e.preventDefault();
$('<iframe style="display:none;"></iframe>')
.prop('src', this.href)
.appendTo('body');
});
});
#app/controllers/uploads_controller.rb
def create
#upload = Upload.new(params[:upload])
if #upload.save
render :json => [{
:pic_path => #upload.attachment.url.to_s ,
:name => #upload.attachment.instance.attributes["picture_file_name"]
}], :content_type => 'text/html'
else
render [:json => { :result => 'error'}], :content_type => 'text/html'
end
end
#app/views/uploads/new.html.haml
%link#theme{:href => "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/themes/base/jquery-ui.css", :rel => "stylesheet"}
= stylesheet_link_tag 'jquery.fileupload-ui'
#fileupload
= form_for Upload.new, :html => { :multipart => true } do |f|
.fileupload-buttonbar
%label.fileinput-button
%span Add files...
= f.file_field :attachment, :multiple => true
%button.start{:type => "submit"} Start upload
%button.cancel{:type => "reset"} Cancel upload
%button.delete{:type => "button"} Delete files
.fileupload-content
%table.files
.fileupload-progressbar
%script#template-upload{:type => "text/x-jquery-tmpl"}
%tr{:class => "template-upload{{if error}} ui-state-error{{/if}}"}
%td.preview
%td.name ${name}
%td.size ${sizef}
{{if error}}
%td.error{:colspan => "2"}
Error:
{{if error === 'custom_failure'}}Custom Error Message
{{else}}${error}
{{/if}}
{{else}}
%td.progress
%div
%td.start
%button Start
{{/if}}
%td.cancel
%button Cancel
%script#template-download{:type => "text/x-jquery-tmpl"}
%tr{:class => "template-download{{if error}} ui-state-error{{/if}}"}
{{if error}}
%td
%td.name ${name}
%td.size ${sizef}
%td.error{:colspan => "2"}
Error:
{{if error === 1}}File exceeds upload_max_filesize (php.ini directive)
{{else}}${error}
{{/if}}
{{else}}
%td.preview
{{if thumbnail_url}}
%a{:href => "${url}", :target => "_blank"}
%img{:src => "${thumbnail_url}"}/
{{/if}}
%td.name
<a href="${url}"{{if thumbnail_url}} target="_blank"{{/if}}>${name}
%td.size ${sizef}
%td{:colspan => "2"}
{{/if}}
%td.delete
%button{"data-type" => "${delete_type}", "data-url" => "${delete_url}"} Delete
Edit
Had a quick look at your app, the problem is that you are mixing prototype with jquery. The easiest way around this is to switch to jQuery using jquery-rails.
#Gemfile
gem 'jquery-rails'
Next, run bundle install and then rails g jquery:install.
Then change your app/views/layouts/application.erb to this:
<%= stylesheet_link_tag :all %>
<%= csrf_meta_tag %>
<%= javascript_include_tag 'jquery.min' %>
<%= javascript_include_tag 'jquery-ui-1.8.13.custom.min' %>
<%= javascript_include_tag 'jquery.tmpl.min' %>
<%= javascript_include_tag 'jquery.iframe-transport' %>
<%= javascript_include_tag 'jquery.fileupload' %>
<%= javascript_include_tag 'jquery.fileupload-ui' %>
<%= javascript_include_tag 'jquery_ujs' %>
<%= javascript_include_tag 'application' %>
Note that I removed the
<%= javascript_include_tag :defaults %>
So that I can specify the order in which jquery, jquery_ujs, and application are loaded.
I've begun with a very similar task recently, and the swf plugin (at least the more recent one) will indeed let you update paperclip's record. It has callbacks for just about everything you'd need to extend.
:onUploadComplete (upload_options,event)
Here's Nathan Colgate's gist on the matter. He just makes a remote call to the rails server once the upload is finished telling it of the locations for the paperclip attachment.
from his uploadCompleteHandler
var uploadCompleteHandler = function(upload_options,event){
$.ajax({
url: '<%= notify_rails_of_successful_upload_path(:format => :js)%>',
global: false,
type: 'POST',
data: ({
'authenticity_token' : '<%= form_authenticity_token %>',
'upload' : {
'file_file_name' : upload_options.FileName,
'file_file_size' : upload_options.FileSize,
'file_content_type' : upload_options.ContentType
}
}),
dataType: 'script'
}
)
};
I'm not sure if this exact callback gets triggered for each file; it definitely looks like it would. But he passes everything paperclip needs back through an ajax request. filename,size,content-type. This way all that gets sent to heroku is some text about the file, sparing your app a good amount of work by giving it to the client.
edit: flash is the only way I've found to avoid sending a lot of data through heroku to s3. There are a few html5/js-only uploaders that might be able to get the job done, but the ones I have found are still pretty ripe on the dev tree.
As per Heroku support, see this.
Paperclip & multiple files upload, although not S3 specific.
View: (notice the array blog_post[avatars][])
<form accept-charset="UTF-8" action="/blog_posts" enctype="multipart/form-data" id="new_blog_post" method="post">
<div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="✓" />
<input name="authenticity_token" type="hidden" value="<%=form_authenticity_token %>" />
</div>
<p><input id="blog_post" name="blog_post[avatars][]" type="file" multiple /></p>
<p><input name="commit" type="submit" value="Upload" /></p>
</form>
Controller:
# POST /blog_posts
# POST /blog_posts.json
def create
#blog_post = BlogPost.new(params[:blog_post])
#blog_post.avatars.each do |avatar|
each_blog_post = BlogPost.new
each_blog_post.avatar = avatar
if each_blog_post.save
end
end
end
Model:
class BlogPost < ActiveRecord::Base
attr_accessible :title, :avatar, :avatars
has_attached_file :avatar
attr_accessor :avatars
end

Resources