I am sending emails in a background job using ActionMailer. Users can create new email templates but they aren't recognized until the background job is restarted. Used to use
ActionView::TemplateFinder.reload!
which forced reloading of templates (now deprecated on 2.3.4). I have tried
ActionView::Base.cache_template_loading = false
but that does not work.
What I wound up doing was setting a global variable in my background process before the Rails environment was loaded:
$background = true
then in environments/production.rb:
config.action_view.cache_template_loading = !$background
Not thrilled, but it works. I get template reloading for email templates in my background job but cached view templates for the online application.
Since your users can create (and possibly change) templates, why don't you store them on the database and render as inline erb?
render :inline => template_record.contents
Now that I suggested this, I noticed... You can also use :inline to manually read the template and pass it to ActionView. You'll have to handle the exceptional case of the template not existing, though.
render :inline => File.read( ... )
Related
I have a file under app/assets/javascripts/templates.js.erb which loads templates from other html views.
= javascript_include_tag "templates.js"
In development mode, my templates are changing very often so templates.js.erb should be re-processed at every page load. But it is cached unless the code in the file changes.
How can I force rails to re-execute templates.js.erb at every page request in development mode?
you can simply use your js code inside <script> tag in layout or particular views for reloading it
Thanks –
you can check in controller wether the request is ajax or not by checking request.xhr? so you
can chached your action conditionally
for example
caches_page :show, :if => lambda { !request.xhr? }
I need to be using double quotes on my attributes due to a Javascript framework issue I am having, and I have tried setting the Haml::Template.options hash as the documentation recommends when using Rails, however isn't taking affect for the 'assets' folder, regardless of where I am setting the option. Note, it is working on normal ActionView templates being rendered by Rails controllers, but not in templates I have under {Rails.root}/app/assets/javascripts/templates/*.html.haml
This is what I have in {Rails.root}/config/initializers/haml.rb:
Haml::Template.options[:attr_wrapper] = '"'
# Adds the ability to use HAML templates in the asset pipeline for use with
# Batman.js partials
Rails.application.assets.register_mime_type 'text/html', '.html'
Rails.application.assets.register_engine '.haml', Tilt::HamlTemplate
I've also tried changing the register_engine to use Haml::Engine and Haml::Template, which both render, but still don't take my options I set above.
How do I set the Haml options for rendering in the asset pipeline? It seems like I need to pass in options for the Sprocket engine?
I found the solution here.
It's all about monkey patching.
I prefer this variation, as it keeps the options already set for Haml::Template.
Put this at the end of your haml initializer.
class Tilt::HamlTemplate
def prepare
options = #options.merge(:filename => eval_file, :line => line)
# Use same options as Haml::Template
options = options.merge Haml::Template.options
#engine = ::Haml::Engine.new(data, options)
end
end
How would this be updated for Rails 3.1?
http://railscasts.com/episodes/88-dynamic-select-menus
I just can't figure out how to call the js.erb file and have it run the code to generate the javascript dynamically.
Might be something: in Rails 3.1, you're most likely using jQuery instead of Prototype. The example code on the Railscasts site is using good old Prototype instead of the new hotness that is jQuery (default javascript library in Rails 3.1).
Once all your jquery pipes are connected, having rails respond to and render your js.erb is the same as always. In your controller:
def country_selected
// whatever you need to do
respond_to do |format|
format.js
end
end
Then in your view directory, you have a country_selected.js.erb that you can put in whatever javascript you want to update the second select menu. (Remember you have to escape your shiz for it to work correctly) e.g.
<%= escape_javascript(params[:country]) %>
By the way, I think .rjs was moved out of Rails proper and into it's own Gem. Something else to keep in mind regarding Rails 3.1 vs. javascript.
I have two RoR3 applications (APP1 and APP2)
www.subdomain1.example.com
www.subdomain2.example.com
and I want to show on APP1 some views from APP2.
I tried to do that using a 'Net::HTTP' request (code in APP1)
Net::HTTP.get( URI.parse("http://www.subdomain2.example.com/users/new") )
but the response is not evaluated as HTTP code. Among other things I do not know if there are other techniques to do what I want in more easy way.
So, is it possible to render partials from APP1 to APP2 using the common and easy approach of rendering partials in the same RoR application?
Example:
render :partial => "/users/new"
If so, how can I do that?
Here, try this:
module ApplicationHelper
require 'open-uri'
def render_url(url)
open url do |f|
f.read.html_safe # remove the 'html_safe' if you're on Rails 2.x
end
end
end
In your view:
<%= render_url 'http://ilikestuffblog.com/' %>
It will work. Just one problem, though: if the site contains relative links to images, other pages, or anything else, those links will not be shown correctly. Try this to see a bunch of blank images:
<%= render_url 'http://www.ducklet.com/' %>
Also, BE WARNED that if you don't own the URL you're including, you will be subject to cross-site scripting weirdness.
If the two applications share a filesystem or have access to a shared filesystem, then you can reference a partial directly by file path. From the Rails guide on rendering:
2.2.4 Rendering an Arbitrary File
The render method can also use a view
that’s entirely outside of your
application (perhaps you’re sharing
views between two Rails applications):
render
"/u/apps/warehouse_app/current/app/views/products/show"
Rails determines that this is a file
render because of the leading slash
character. To be explicit, you can use
the :file option (which was required
on Rails 2.2 and earlier):
render :file =>
"/u/apps/warehouse_app/current/app/views/products/show"
The :file option takes an absolute
file-system path. Of course, you need
to have rights to the view that you’re
using to render the content.
It might be more prudent to create a gem that has any shared code (ie. partials) in it so both apps can use it.
We are generating a newsletter automatically every 24 hours using a rake task. There's a section at the top of the newsletter where an admin can put a customized message. The screen that the admin uses has a live preview of the newsletter (they were insistent on this), rendered using a haml partial that takes a collection.
In order to generate and send the emails, we are sending xml documents to a third party API that contain (among other things) the HTML for the email that we'd like to generate.
What I want to do is save the output of this haml partial within a rake task, something similar to PHP's ob_*() buffering functions. Is there any way to do something like the following:
ob_start();
render :partial => newsletter, :collection => posts
newsletter_html = ob_get_contents()
xml = "
<Creative>
<Name>Our Newsletter -- #{Time.now.strftime('%m/%d/%Y')}</Name>
<HTML><html><body>#{newsletter_html}</body></html></HTML>
...
</Creative>"
I'm probably missing something obvious, and I could think of a few ways to do this but most of them are not DRY and I don't want to be generating a lot of html in the helpers, models, or the task itself.
Let me know if there is a way for me to accomplish this.
A more direct approach from the HAML docs:
require 'haml'
haml_string = "%p Haml-tastic!"
engine = Haml::Engine.new(haml_string)
engine.render #=> "<p>Haml-tastic!</p>\n"
You'll have to do a bit of work loading up the HAML template and setting up any local variables that need interpolation, but the flexibility may make up for that.
A common way to do this (which is typically advised against) is to render into a string in your model or rake task:
cached_content =
ActionView::Base.new(Rails::Configuration.new.view_path).render(:partial => "newsletter", :locals => {:page => self,:collection => posts})
see here for a more full description:
http://www.compulsivoco.com/2008/10/rendering-rails-partials-in-a-model-or-background-task/
If you are using page or fragment caching, you could pull the content out of the cache. The easiest way to do this is to just enable caching, and then look at where the files are being placed.
http://guides.rubyonrails.org/caching_with_rails.html
A bit of a shot in the dark but if you check out the rdoc for Haml it more than likely has a method which accepts a string and some variables and then renders the output.
With ERB it would look something like:
require 'erb'
name = 'world'
template = 'hello <%= name %>'
template = ERB.new(template)
puts template.result(binding)