I am storing customer-specific partials on S3. When I render the value of the S3 object, it renders as text. How can I render it so that it appears within my main layout?
Looks like I just need to:
render :text => myTextFromS3, :layout => true
And it works!
Update: Since 2013 rails changed
There is 3 different ways:
render html: '<strong>HTML String</strong>' # render with `text/html` MIME type
render plain: 'plain text' # render with `text/plain` MIME type
render body: 'raw body' # render raw content, does not set content type, inherits
# default content type, which currently is `text/html`
Source https://github.com/rails/rails/issues/12374
Related
I have an uploader (internal use only) that will upload an HTML document to a binary column of a table in my client-facing website. The client facing site has an index that allows the user to view the page as a normal website (using send_data h_t.html_code, :type => "html", :disposition => "inline"). I also want to give the user the ability to download a PDF of the page. For that I'm using wicked_pdf.
The entire problem seems to stem from the fact that the data is stored in the database. As strange as it sounds, it is vital to business operations that I get formatting exact. The issue is I can't see any image, and the stylesheets/style tags don't have any effect.
What I've tried-
Gsub-
def show
html = HtmlTranscript.find(params[:id])
html_code = html.html_code.gsub('<img src="/images/bwTranscriptLogo.gif" alt="Logo">','<%= wicked_pdf_image_tag "bwTranscriptLogo.gif" %>')
html_code = html_code.gsub('<link rel="StyleSheet" href="" type="text/css">','<%= wicked_pdf_stylesheet_link_tag "transcripts.css" %>')
transcript = WickedPdf.new.pdf_from_string(html_code)
respond_to do |format|
format.html do
send_data transcript, :type => "pdf", :disposition => "attachment"
end
##### i never could get this part figured out, so if you have a fix for this...
# format.pdf do
# render :pdf => "transcript_for_#{#html.created_at}", :template => "html_transcripts/show.html.erb", :layout => false
# end
end
end
Using a template-
#Controller (above, modified)
html = HtmlTranscript.find(params[:id])
#html_code = html.html_code.gsub('<img src="/images/bwTranscriptLogo.gif" alt="Logo">','<%= wicked_pdf_image_tag "bwTranscriptLogo.gif" %>')
#html_code = #html_code.gsub('<link rel="StyleSheet" href="" type="text/css">','<%= wicked_pdf_stylesheet_link_tag "transcripts.css" %>')
transcript = WickedPdf.new.pdf_from_string(render_to_string(:template => "html_transcripts/show.html.erb", :layout => false))
#view
<!-- tried with stylesheet & image link tags, with wicked_pdf stylesheet & image link tags, with html style & img tags, etc -->
<%= raw(#html_code) %>
And both will generate a transcript- but neither will have style OR image.
Creating an initializer-
module WickedPdfHelper
def wicked_pdf_stylesheet_link_tag(*sources)
sources.collect { |source|
"<style type='text/css'>#{Rails.application.assets.find_asset("#{source}.css")}</style>"
}.join("\n").gsub(/url\(['"](.+)['"]\)(.+)/,%[url("#{wicked_pdf_image_location("\\1")}")\\2]).html_safe
end
def wicked_pdf_image_tag(img, options={})
image_tag wicked_pdf_image_location(img), options
end
def wicked_pdf_image_location(img)
"file://#{Rails.root.join('app', 'assets', 'images', img)}"
end
def wicked_pdf_javascript_src_tag(source)
"<script type='text/javascript'>#{Rails.application.assets.find_asset("#{source}.js").body}</script>"
end
def wicked_pdf_javascript_include_tag(*sources)
sources.collect{ |source| wicked_pdf_javascript_src_tag(source) }.join("\n").html_safe
end
end
did absolutely nothing, and I have no idea what to try next.
As a side note, the code to view the HTML version of the transcript is as follows:
def transcript_data
h_t = HtmlTranscript.find(params[:id])
send_data h_t.html_code, :type => "html", :disposition => "inline"
end
It requires no view, as the html data is stored in the database, but I get image, style, etc. Everything works with the HTML version- just not the PDF.
I'm on ruby 1.8.7 with rails 3.0.20.
Solved-
As it turns out, there was more than one issue at hand.
1- Installation of wkhtmltopdf for Ubuntu via $apt-get install does not quite do the trick for what I wanted...
see http://rubykitchen.in/blog/2013/03/17/pdf-generation-with-rails
(there may have also been an issue with having not previously run sudo apt-get install openssl build-essential xorg libssl-dev libxrender-dev, as when I did, it installed a number of components I did not previously have.)
2- The HTML files I had uploaded contained image & style code that was breaking the formatting. I fixed it with this...
def rm_by_line(which = 0, line1 = 0, line2 = 0)
h_t = HtmlTranscript.find(which)
line_by_line = h_t.html_code.split('
')
for i in line1..line2
line_by_line[i] = ''
end
line_by_line = line_by_line.join('
').strip
return line_by_line
end
Then, all I had to do was pass which lines I wanted to remove.
(I had to split the parens with a carriage return because '\n' didn't function properly when calling 'raw' on the returned string.)
3- wicked_pdf_stylesheet_link_tag and wicked_pdf_image_tag were undefined. I had to inline the style formatting I wanted into a layout I created (turns out wicked_pdf_stylesheet_link_tag used asset pipeline wich my ruby/rails did not implement, which also means I had to get rid of the javascript helpers) and created a helper for wicked_pdf_image_tag, making a switch in the layout for which image tag (image_tag or wicked_pdf_image_tag) to be used.
4- I needed both a .html.erb & a .pdf.erb for my templates, so I made both.
5- Got rid of WickedPdf.new.pdf_from_string in favor of linking to either html or pdf by using :format => 'html' or :format => 'pdf' in the link_to tag.
I have a controller where I set layout to false:
class SplashController < ApplicationController
layout false
def index
end
end
But when I load this page there is no css whatsoever - I assume this has to do with how rails handles layout false - but my current knowledge of rails leaves me lost.
How do I not render a layout, but still load all the other assets (css, js, etc. . .) that would typically load if I were to load a layout? (*Note that the layout file has no specific reference to any of these assets)
By default, if you use the :text option, the text is rendered without using the current layout. If you want Rails to put the text into the current layout, you need to add the :layout => true option.
As you need only the information to be displayed, I suggest to use :text to render.
You can send plain text – with no markup at all – back to the browser by using the :text option to render:
render :text => "OK"
NOTE: Rendering pure text is most useful when you’re responding to AJAX or web service requests that are expecting something other than proper HTML.
UPDATE:
Also if you want that assets should be shown but still layout should be false then you have to render layout to false after making the assets available. This means you make some view, then define your required css and js files there and then call that view from controller and then set layout to false.
Setting the layout to false after view will show the css and js stuff but still keep the layout to false.
But setting the layout to false before showing the view that contains css and js will not include assets at all.
The other alternative of the above will work also:
css : <%= eval("render :partial => 'myurl/blah', :formats=> [:css], :layout => false").dump.html_safe %>
You see that how partial view that contains your assets like :css is getting called while layout is false.
I wanna override html code when working with active_admin gem in Rails; because the nav-bar and many elements in these gem's views are different with my views (other pages). I hope that has a way to change html code without changing css manually! Thanks
It is not very easy , activeadmin use DSL for building html (called "Arbre")
You have to monkey patch every page class, also , it may prevent customizing of css too.
For example to move sidebar to left, create initializer with next patch.
class ActiveAdmin::Views::Pages::Base < Arbre::HTML::Document
def build_page_content
build_flash_messages
div :id => "active_admin_content", :class => (skip_sidebar? ? "without_sidebar" : "with_sidebar") do
build_sidebar unless skip_sidebar?
build_main_content_wrapper
end
end
end
default method was
def build_page_content
build_flash_messages
div :id => "active_admin_content", :class => (skip_sidebar? ? "without_sidebar" : "with_sidebar") do
build_main_content_wrapper
build_sidebar unless skip_sidebar?
end
end
The full list of classes used for rendering can be found here , so some of them you need to patch.
https://github.com/gregbell/active_admin/tree/master/lib/active_admin/views
Be ready for a big piece of work.
UPD. Gem for changing activeadmin sidebar position
https://github.com/Fivell/active_admin_sidebar
All.
A Rails n00b here...
I'm writing an application that reports the status of a transaction.
Some of the content in the rendered HTML comes from instance variables
initialized in the controller, while other content comes from text files
(e.g., log files) that I want to render in the HTML using <pre> tags.
What is the "Rails Way" to do this?
Thank you for your time...
<pre>
<%= render :file => '/tmp/test.log' %>
</pre>
Here you go: http://edgeguides.rubyonrails.org/layouts_and_rendering.html
In some cases (when the file is not small and loading it is connected with a delay), I prefer to load the page content and then to use jQuery ajax request to load the file content.
For example, let's say I have a model with file path attribute. In the view layout I am doing something like this:
<pre data-source=" <%= (#file.path) %>"></pre>
Then in the corresponding js file I am loading the context like this:
$(document).ready ->
$.ajax(
url: $("pre").data("source")
context: document.body
).done (response) ->
$("pre").html response
return
return
Of course you can check the jQuery ajax documentation for more options. For example, you can render the pre tag with loading like this:
<pre data-source=" <%= (#file.path) %>"><div class="loading"></pre>
or use other jQuery animations as well.
To implement Gravatar in my Rails3 application, I'm using the gravatar_image_tag gem in a helper, but I'm having issues when mixing 2 config options:
If the user doesn't have a gravatar attached to his email a default image is rendered; but I want it to reference an external file (e.g., http://www.iconfinder.com/ajax/download/png/?id=43350&s=128 instead of :identicon or others)
I also want the image to be resized on the fly to, let's say 50px.
Independently, both options work as expected, but when I put them together:
def gravatar_for(user, options = { :default => 'http://www.iconfinder.com/ajax/download/png/?id=43350&s=128', :size => 50 })
gravatar_image_tag(user.email.downcase, :alt => user.full_name,
:class => 'gravatar',
:gravatar => options)
end
the size option is not applied, and the gravatar gets rendered in it's full size (128px in this case).
What am I doing wrong, or how can I achieve this combination?
Gravatar will not resize your default image for you. I assume that it just 302s to the ulr gave as a default if it does not find an gravatar for the email you gave it. It looks like the 's' parameter in the iconfinder url is for the size you are trying to grab but that icon does not have a size of 50px available only 128, 256, and 512
Example:
http://www.iconfinder.com/ajax/download/png/?id=43350&s=256
If you wanted a 50px and 80px versions of the icon I would save it to your applications public/image directory as default_gravatar_50.png and default_gravatar_80.png respectively and change your method like so.
end
def gravatar_for(user, options = {})
options = { :size => 50 }.merge(options)
options[:default] = image_tag("default_gravatar_#{options[:size]}.png
gravatar_image_tag(user.email.downcase,
:alt => user.full_name,
:class => 'gravatar',
:gravatar => options)
end
Or if you find an icon on icon finder that is the size(s) you like change the setting of the default option like so.
options[:default] = "http://www.iconfinder.com/ajax/download/png/?id=43350&s=#{options[:size]}"
Iconfinder here. You don't want to link to the download script. Instead just grab the URL to the image it self so you wan't get a lot of header information.