I'm looking to do a random image in ruby on rails in the background via css. The difference being I want to also display a attribution to the person who took the image. I'm only going to have 5 images so don't see the need for a database. I want to keep it low maintenance. What is the best way to extend the following?
<style type="text/css">
html {
background: url(<%= randomized_background_image %>) no-repeat center center fixed;
}
</style>
Now in your application_helper
def randomized_background_image
images = ["assets/foo.jpg", "assets/random.jpg", "assets/super_random"]
images[rand(images.size)]
end
Well, first a disclaimer, I don't think you should be doing this. Embedding Ruby in CSS is pretty sloppy. Why? It crosses abstraction layers and mixes concerns unnecessarily.
Ruby (and erb templates generally) really don't have a great model of your document object, but guess who does? Jquery! :) So as an alternative, take a look at the $ examples in the answers to this question: Random background images CSS3
That said, to do this in Ruby, the way to do it would be to have a hash object for each of your images then put them in your array, ie:
image_hash = Hash[url: 'http://', attribution: 'Author K. Dude']
=> {:url=>"http://", :attribution=>"Author K. Dude"}
image_hash[:url]
=> "http://"
array_of_image_hashes = Array[image_hash]
=> [{:url=>"http://", :attribution=>"Author K. Dude"}]
array_of_image_hashes.first[:url]
=> "http://"
This way you could share the same local variable (a random index of your array) in your view both at the style level and just as a string in a span underneath it. So, <%= random_image_result[:url] %> in style and <%= random_image_result[:author] %> in a span. I'm guessing you're doing Rails, and if so, I'd recommend putting your generator method in a helper, which is included automatically at the controller level so it is available to your view.
Related
I am willing to change a picture based on the choice of the language. It is because my image contains some text and I made three different versions of the image according to language choice (Dutch, French and English). How do I need to do that?
I tried to add my
<%= image_tag("lansink_en.png", class: "center-image") %> in my different en.yml, fr.ymland nl.yml files but it didn't work out.
Thanks for your help!
You can escape the html content in your yaml files. So say you have a yml like
en:
url: '<%= image_tag("lansink_en.png", class: "center-image") %>'
Then to display it you do:
<%= raw t('url') %>
Then just set your other locale files and you're all set
I am of the opinion that translation files should not contain code or any more specific markup than is strictly semantic.
If they get shipped to translators (or auto-translated with something like Google Translate), then English code could get translated, leaving you with something broken in one or more languages, and something working in the others.
If you change your class-names, it shouldn't require a round of translation or a bypass for this special case.
I'd prefer a good-old helper method:
module SomeHelper
def lansink_image_tag
image_tag("lansink_#{I18n.locale}.png", class: "center-image")
end
end
Or, if you don't know that all languages will necessarily have a file, but you want a fallback:
module SomeHelper
def lansink_image_tag
has_image = [:de, :fr, :en]
suffix = has_image.include?(I18n.locale) ? I18n.locale : :en
image_tag("lansink_#{suffix}.png", class: "center-image")
end
end
I have a div that has a dynamic background image. The background image url is logged in a database. I'd also like to replace this image with a dynamic GIF (which is logged in the same table) when the div is hovered over...but I'm struggling with figuring out a clean way to do this.
Here is a brief snippit from the html.erb file I'm working with...it seems that I cannot use the hover selector in in-line HTML, so I'm not sure if I need to resort to JavaScript? I'd essentially like to replace blah.jpg with blah.gifon:hover.
<% #workout[:image_url] = "blah.jpg" %>
<% #workout[:gif_url] = "blah.gif" %>
<div class="image-wrapper">
<div class="workout-image" style="background-image:url(<%= #workout[:image_url] %>)">
</div>
</div>
EDIT:
It works now using <script> tags.
<head>
<script>
document.head.insertAdjacentHTML('beforeend', '<style>.workout-image:hover { background-image:url("blah.gif");}</style>');
</script>
</head>
Unfortunately this can't be solved using raw CSS, as you can't target pseduo-selectors with inline CSS. However, it's possible to get around this using JavaScript. What you need to do is add the following to your page:
<script>
document.head.insertAdjacentHTML('beforeend', '<style>.workout-image:hover{background-image:url(<% #workout[:gif_url] %>);}</style>');
</script>
That should append CSS styling of .workout-image{background-image:url("blah.gif");} to the end of the head section.
Another solution would be to simply use an external css.erb file instead of a .css file, in order to process Ruby variables directly:
.workout-image:hover {
background-image:url(<% #workout[:gif_url] %>);
}
Be aware that using ERB in CSS will only work if the file is loaded ad-hoc, and will not work if you precompile your assets! You can get around this using the SCSS Rails Preprocessor, assuming you have access to, and want to use, SASS.
Hope this helps :)
Motivation and Problem
There are several libraries for generating html markup strings using ruby (erb, haml, builder, markaby, tagz, ...), but I am not satisfied with any of them. The reason is that, except for erb, they take the nesting style rather than the chain style. And erb is a way to embed ruby within html rather than generating html with ruby.
To my understanding, one beauty of ruby lies in encouraging the use of chain style:
receiver.method1(args1).method2(args2). ... method_n(args_n)
instead of doing a nesting style:
method_n(...method2(method1(receiver, args1), args2), ... args_n)
But libraries mentioned above (except for erb) take the nesting style (sometimes with the help of block arguments).
My Idea
For my own purpose, I wrote a method dom so that I can do html markup in a chain style. When applied to a string, this example
"This is a link to SO".dom(:a, href: "http://stackoverflow.com").dom(:body).dom(:html)
will generate:
<html><body><a href="http://stackoverflow.com";>This is a link to SO</a></body></html>
When applied to an array, this:
[
["a".dom(:td), "b".dom(:td)].dom(:tr),
["c".dom(:td), "d".dom(:td)].dom(:tr)
].dom(:table, border: 1)
will generate
<table border="1";>
<tr>
<td>"a"</td>
<td>"b"</td>
</tr>
<tr>
<td>"c"</td>
<td>"d"</td>
</tr>
<table>
And, when applied without an explicit receiver (outside of a domain of strings and arrays),
dom(:img, src: "picture.jpg", width: 48, height: 48)
will generate
<img src="picture.jpg";width="48";height="48";/>
Note that all is done with just one method dom. This is much simpler than using other libraries. It is also flexible in that it is not affected by a change in the inventory of html tags; you just specify that with a symbol argument. In other libraries, there are classes and/or methods for each tag. Furthuremore, unlike erb, it is pure ruby. It is not a DSL that needs to be convertred.
My Implementation
The implementation is as follows:
class Hash
def attribute
map{|k, v| %Q{#{k}#{
case v
when TrueClass; ''
when Hash; %Q{="#{v.subattribute}"}
else %Q{="#{v}"}
end
;}}}.join
end
def subattribute
map{|k, v| %Q{#{k}:#{v};}}.join
end
end
class Array
def dom type, hash = {}
"<#{type} #{hash.attribute}>\n#{join("\n").gsub(/^/, " ")}\n</#{type}>"
end
end
class String
def dom type, hash = {}
"<#{type} #{hash.attribute}>#{self}</#{type}>"
end
end
class Object
def dom type, hash = {}
"<#{type} #{hash.attribute}/>"
end
end
Questions
Are there already stable libraries that do a similar thing?
What will be the potential problems to this approach (particularly to my implementation or to doing this in chain approach)?
Some attributes take boolean values, which are often encouraged to be omitted. For example, <input type="text";readonly> instead of <input type="text";readonly="true">. In my present implementation, I can do that by passing true (which will not be used in the end) as the value for such attribute like dom(:input, type: "text", readonly: true), but that seems redundant and is also part of the reason that I have case statement in the code, making it slower. Is there a better way to do this?
Are there any possible improvements to the implementation?
The main reason of haml and most other nested stuff is that it is basically easy to look how your HTML is nested. I am assuming this but do you actually code HTML or do you do more backend stuff? The reason for it is that in nested style, you will see how your elements are nested(which is important to you if you are also writing the styles)
While it is quite easier to write
.dom(:body).dom(:html)
it is difficult for a designer to see how the HTML flows without mapping and trying it to visualize in his head, whereas:
%html
%body
does that already with just one look.
Take not of a longer example:
"This is a link to SO".dom(:a, href: "http://stackoverflow.com").dom(:body).dom(:html)
Would it be easier for you if say the client or you needed to add a clickable image to the link? How would you have done it? In haml it is easy as:
%html
%body
%a{:href => "blah"}
= image_tag("image.png")
Also, IMHO, writing dom(:) for each html tag is just as tedious as writing the closing tag for it(which HAML and the others fixed)
Again, these are just my opinions from an XHTML/CSS programmer(as opposed to a ruby programmer perspective)
And lastly, I would also think that this can be turned into a community wiki or something as this doesn't merit an exact answer and will probably spawn a lot of subjective ones like this one.
I am trying to search/select a link in a page that is underlined, while others are not. The source is something like this:
<a href="someurl1">
<b>
<u>Some ulined text</u>
</b>
<u></u>
</a>
<br>
Other link text
<br>
Another Link text
<br>
I tried something like
link = browser.link(:u?, true)
link.exists?
I get the following errors
TypeError: expected one of [String, Regexp], got true:TrueClass
from /usr/lib/ruby/gems/1.8/gems/watir-webdriver-0.2.4/lib/watir-webdriver/locators/element_locator.rb:152:in `check_type'
from /usr/lib/ruby/gems/1.8/gems/watir-webdriver-0.2.4/lib/watir-webdriver/locators/element_locator.rb:189:in `normalized_selector'
from /usr/lib/ruby/gems/1.8/gems/watir-webdriver-0.2.4/lib/watir-webdriver/locators/element_locator.rb:188:in `each'
from /usr/lib/ruby/gems/1.8/gems/watir-webdriver-0.2.4/lib/watir-webdriver/locators/element_locator.rb:188:in `normalized_selector'
from /usr/lib/ruby/gems/1.8/gems/watir-webdriver-0.2.4/lib/watir-webdriver/locators/element_locator.rb:76:in `find_first_by_multiple'
from /usr/lib/ruby/gems/1.8/gems/watir-webdriver-0.2.4/lib/watir-webdriver/locators/element_locator.rb:33:in `locate'
from /usr/lib/ruby/gems/1.8/gems/watir-webdriver-0.2.4/lib/watir-webdriver/elements/element.rb:260:in `locate'
from /usr/lib/ruby/gems/1.8/gems/watir-webdriver-0.2.4/lib/watir-webdriver/elements/element.rb:247:in `assert_exists'
from /usr/lib/ruby/gems/1.8/gems/watir-webdriver-0.2.4/lib/watir-webdriver/elements/element.rb:31:in `exist?'
Edit:
So I am actually using this for screen scraping rather than testing. That may explain the reasons why watir does not support this directly since CSS and other better practices make sense for testing and when you the HTML development and testing go hand in hand. Hoserver from a scraping perspective, the text formatting is what the user sees, and searching underlined, bold links etc. make sense for scraping.
I've never seen that kind of attribute used in a test case before. I also haven't seen any code support for it. You may have to roll your own. Here is an example borrowed from Zeljko
def hasUnderlined(browser)
s = false
browser.links.each do |l|
if l.html.downcase.match /\<u\>*\<\/u\>/
s = true
end
end
end
def getUnderlined(browser)
browser.links.each do |l|
if l.html.downcase.match /\<u\>*\<\/u\>/
return l
end
end
end
I don't think what you want is possible directly because the underline is not an attribute of the link tag, but a formatting tag that apples to just the text in the link.
However, in modern web pages, formatting is often controlled by a combination of CSS and attributes such as class names, which ARE something you could specify when identifying a link. So IMHO your best bet here might be to talk a little with your developers about how they are coding the site and see if they are perhaps open to increasing the testability of their code by using slightly more modern techniques for controlling what links are underlined, such as say using CSS and basing the underlining on a class name. (There's a lot of other good reasons to use CSS for controlling formatting instead of embedding it directly in the HTML, but unless your guys are fresh off the html-banana-boat so to speak, they should not need to be taught why using CSS is a good thing)
That would let you search for a link according to the class attribute that was being used to cause CSS to underline the text
If your developers are not open to such an approach to make their code more testable, then I think your only option is going to be to create your own ruby code for this and modify your copy of water (see #Dave's answer), and then be prepared to maintain that custom patch any time you update watir etc.
So, the only thing you know about a link is that it is underlined?
I thought this would do it (using the latest watir-webdriver gem):
browser.link.u.click
But I got this:
NoMethodError: undefined method `u' for #<Watir::Anchor:0x00000100cbb3c0>
Jari (watir-webdriver developer) said he thinks u tag is not in HTML spec.
By the way, this works:
browser.link.b.click
Jari suggested trying xpath, but I thought css selectors would be nicer to read. Here it is:
browser.element(:css => "a b u").click
Should I be using the content_tag helper for all html tags when working with Rails?
Is it The Rails Way to use content_tag for even simple things like Header tags?
<%= content_tag :h2, :class => "bla bla" do %>
Header
<% end %>
vs.
<h2>Header</h2>
Clearly just using straight html is much 'simpler' and 'shorter', but what is the correct Rails Way of doing things?
Using content_tag when you don't have to is a waste. There's no need to use ERBisms to generate static HTML so don't do it. If some other piece of code determines what tag to use, then you'd use content_tag to construct that tag.
If you are asking the rails way of doing this, then its defiantly using 'content_tag', but using tag_helpers has its own advantages and disadvantages
Personally for me I can see these things, (Using rails helpers instead of pure HTML)
Advantages
1 - Your code will be cleaner. (with less lines)
2 - You will have more control other the elements.
Ex: You can have your own helper tags like 'big_text_box' which will return a text box more than the normal with and you can use it across all the site
3 - You will be able to add attributes like class, id dynamically in the runtime
Disadvantages
1 - If you have a separate designer (I mean UI engineer) he/she will get confuse of by the code you have use. As its not pure html
2 - Its slow than the pure html (But this will not even noticeable unless otherwise your app is a damn major one...)
So its up to you to decide what to use, personally I prefer using rails helper tags as it makes me more comfortable
HTH
cheers
sameera
One useful method is the "div_for", which is somewhat similar to the content_tag. If you find yourself marking up HTML elements with data you can reference later, "div_for" makes your life much easier.
Let's say you have a bunch of people being shown on a page and you need to wrap each with a div that has a unique ID so you can modify these elements with JS. By hand and straight HTML you would have to do:
<% #people.each do |p| %>
<div id="person_<%= p.id %>"><%= p.name %></div>
<% end %>
That would get bothersome if you were doing LOTS of this with multiple attributes (I commonly use custom IDs, classes, and some data attributes). But using div_for you could write the above as:
<% #people.each do |p| %>
<%= div_for(p) do %><%= #person.name %><% end %>
<% end %>
Makes the HTML a little easier to read when things get long and complex. I found it is much cleaner when working with javascript a lot.
http://apidock.com/rails/ActionView/Helpers/RecordTagHelper/div_for