I have a table defined in slim:
table
tr
td
=_("Some Content")
td
=_("Some Content")
I would like to add some classes to certain td tags. I can do so like this:
table
tr
td.extraclass
=_("Some Content")
td
=_("Some Content")
This adds "extraclass" to that td:
<td class="extraclass"> Some Content </td>
How can I add a class by embedding some rails/ruby into this? In normal rails I could do:
<td class="<%=#article.attribute%>">
How do I do this here? I don't think I can do:
td.=_(#article.attribute)
But I would like to add classes in some similar way here. Anybody have any advice? if I have not been clear in what I'm attempting to do, please let me know what I can add.
The doc for this feature is here:
td class="#{#article.attribute}"
According to the documentation here you can achieve this as follows:
td class=#article.attribute
Btw., when writing td.class1 class=some_ruby_exprthe two classes will automatically be merged into the resulting class attribute.
Related
Hello i need some help with shopware.
My question is probably pretty basic but i cannot get it done. I want to print out attributes from an article. In shopware documentation they call them {$sArticle.attr1} till {$sArticle.attr20} but they can also have different names so i cannot refer directly to the name and instead i want only a few attributes to be printed.
so far i know that all attributes are stored in the s_articles_attributes database table and i only want to print out those columns when the column name containes='artikelattribut_'
The code is going to be implemented in a table from frontend/detail/tabs --> description.tpl
the actual table already uses the $sArticle.sProperties and the code looks the following:
{if $sArticle.sProperties}
<div class="product--properties panel has--border">
<table class="product--properties-table">
{foreach $sArticle.sProperties as $sProperty}
<tr class="product--properties-row">
{* Property label *}
{block name='frontend_detail_description_properties_label'}
<td class="product--properties-label is--bold">{$sProperty.name|escape}:</td>
{/block}
{* Property content *}
{block name='frontend_detail_description_properties_content'}
<td class="product--properties-value">{$sProperty.value|escape}</td>
{/block}
</tr>
{/foreach}
</table>
</div>
{/if}
The thing is that $sArticle.sProperties and {$sArticle.attr1} till {$sArticle.attr20} are different. All i want is a second {foreach} that loops threw all article attributes maybe the idea is getting clear with that:
{foreach $sArticle.attr FROM s_articles_attributes WHERE name contains='artikelattribut_'}
I hope somebody understands my problem. Thankfull for any advice.
Thanks
First, keep in mind, that "properties" and "attributes" mean something different in Shopware as you might know it from other shop systems.
"Properties" are used for characteristics of a product, like the taste or colour of product.
"Attributes" in Shopware do not have anything to do with attributes in the usual meaning. You can find those *_attributes tables for almost every entity and they are used more like custom fields or columns which you could add to the entities to extend them with custom data.
Now back to your problem. Try this:
{foreach $sArticle.attributes.core->toArray() as $attributeName => $attribute}
{$attributeName|var_dump}
{$attribute|var_dump}
{/foreach}
There are two ways to access the attributes of a product.
All attributes are directly assigned to the $sArticle variable and you can use them, as you already described in your text.
Attributes are also stored in $sArticle.attributes where you can find different types of attributes. By default those are core and marketing for products on the detail page. Be aware that the values of those keys are objects of type Shopware\Bundle\StoreFrontBundle\Struct\Attribute. That's why we need to call the toArray method, to get an array which we can iterate.
I'm writing a parser and want to take element only with class name "row1 processed"
<tbody class = "processed"> some data1 </tbody>
<tbody class = "row1 props processed"> some data2 </tbody>
<tbody class = "row1 processed"> some data3 </tbody>
via gem nokogiri.
I can do it for row1, processed, props; but I need only "row1 processed"
test = el.css('tbody.row1')
test = el.css('tbody.processed')
How can i do this?
I'm using ruby on rails 5.2.2
Update
When I typed el.css('tbody.row1.props') it displayed informaton from this
element
<tbody class = "row1 props processed"> some data2 </tbody>
but when I added "processed" class then I got nothing...
Separate multiple classes with dots:
el.css('tbody.row1.processed')
As mentioned on the Ruby developers Slack channel, the underlying issue here is that Nokogiri can only access the initially loaded HTML from the page (what you see when you click View Source), before it has been modified by JavaScript. This is why it's not accessible in Nokogiri, since at this point the processed class hasn't been loaded. The other answer here works if the HTML is available on page load.
If you need to modify a page after it has been modified by JavaScript, you have two choices: either use JavaScript to access newly-modified DOM elements, or rethink how you parse the web page to get what you want.
Earlier Prawn gem allowed to create a table by its html representation (having an html table string as an input argument like <table class="abc"> .... </table>). Now I didn't find this facility in the manual.
So is it possible now? If not, is there any other option then?
TL;DR: if your use-case is 1) generating both HTML and PDF data (like online invoices etc.), and 2) making sure both look the same, then Prawn is not really the best solution (which is the same suggestion in the Prawn Readme).
In your case, you could parse the HTML using Nokogiri or Upton and extract the data from the HTML table and then use it to generate the PDF representation via Prawn. The HTML styles may not directly translate into the ones used by Prawn and so, even with a lot of code-wrangling, you might not achieve the consistency in styling — which I assume, from the comments on the answer by royalGhost, is the result you want. Also, a simple Nokogiri parsing solution won't work if your HTML table is nested and the parsing code does not cater to that. For example, consider this:
<table>
<tr>
<td>First Column, First Row</td>
<td>Second Column, First Row</td>
</tr>
<tr>
<table>
<tr>
<td>First Column, Second Row</td>
<td>Second Column, Second Row</td>
<td>Third Column, Second Row</td>
</tr>
</table>
</tr>
</table>
Then, in the Ruby parsing snippet, you should ensure that the inner <table>...</table> is parsed into a Prawn::Table object and not a row of Prawn::Table::Cell objects.
Any wkhtmltopdf based options such as WickedPDF or PDFKit offer much cleaner way of achieving the HTML to PDF conversion solution.
You have two options:
Ditch Prawn entirely and prefer the solution above.
Use Prawn by extracting the data from the HTML via Nokogiri/Upton and generate the PDF and not worry about styling being the same as that in the HTML representation.
Well you can use prawnto gem for templates to create table using prawn.
For e.g if you define the following templates, it will draw table with 3 columns with x, y and z width.
data = [ ["Column 1", "Column 2", "Column 3"] ]
table(data, :column_widths => [x,y,z], :cell_style => { :inline_format => true })
Rails 2.3.5 (internal work server - stuck at this version for inside apps)
The company 'standard' browser where I work is IE and about 70% of users are using IE7.
What I've slowly been learning (IE7 only) is that if you have FORM beginning or end tags inside a TR or TD, IE7 will create extra lines, sometimes doing very odd things. My solution so far is to put FORM beginning and end tags outside the TABLE tags.
Then, because I want a single line break between tables ... if I use a tag after tables in IE7 only I'll get 3 blank lines between tables where in every other browser there will just be a single line.
Right now I'm dealing with a simple table list of users with a form on each line (delete or change access level). After playing around A LOT with this, IE7 messes up the least when I place the FORM and FORM END tags inbetween table tags like:
<table class="table_standard_blue">
<tr>
<td>
FOO
</td>
</tr>
<% users.each do |user| %>
<% form_for(user) do |f| %>
<tr>
<td>
SOME SELECT / SOME BUTTON
</td>
</tr>
<% end %>
<% end %>
</table>
While the 'guts' of the table will look fine this way, the problem this leaves behind is basically what looks like an extra line break above and below the table (in IE7 only). If I have a couple of tables like this, the effect magnifies and it looks like two blank lines between tables (where in IE8/Firefox) there will be no blank lines.
I know there's something about RAILS putting extra spaces in with FORM tags (and there's suppose to be some fix in RAILS 3 - which I can't use of course at work). Does anyone have any idea how I could fix or hide what's going on in IE7?
Thanks - much appreciated.
I'm not sure you're allowed to place form tags around tr elements, but to answer your question:
Use CSS to reduce the margin-top and margin-bottom of the tables. Before that, though, are you using the right DOCTYPE declaration? That's important to make sure IE7 isn't falling back to emulate layout quirks from IE6 or something.
Before you try what Satya suggested you can try to wrap the form into a span-tag; not sure if it works here but worth a try.
Thanks for the help. Span tags didn't have any affect at all. Also, I went throught multiple doc types and none of them mand any difference. I kept google searching and found a solution though. I'm not 100% sure but it seems to be a problem with IE7 and forms in general (not something a RAILS form_for is doing). Adding this into my stylesheet fixed everything:
FORM
{
display: inline;
}
What I know:
Rails has the cycle() method that enables odd/even rows in a table to have different CSS classes. We can pass multiple classes to the cycle() method and that works great.
I wanted rows which are grouped in three's; so, I used this:
...some html-table code...
<tr class="<%= cycle("table_row_1","table_row_2","table_row_3","table_row_4","table_row_5","table_row_6") %>">
...some more html-table code...
The corresponding CSS I defined is:
.table_row_1 { background-color: red;}
.table_row_2 { background-color: red;}
.table_row_3 { background-color: red;}
.table_row_4 { background-color: blue;}
.table_row_5 { background-color: blue;}
.table_row_6 { background-color: blue;}
It works, but it doesn't feel "clean".
Is there a recommended way to do this in Rails ?
UPDATES
On similar lines to #Ryan Bigg's answer, is it possible to generate strings in sequence so that the cycle() method can be sent strings of the form prefix_1 prefix_2 prefix_3 somehow using the *3 syntax or some other way?
The inspiration to use this "every third row" striping came from an article on Edward Tufte's site
It seems CSS3 can do this (link), but that's not widely supported at this time :(
Not related to question, but I just searched for this problem I have on Google, and the questions listed at questionhub.com! I never asked this on questionhub.com!
Now its on http://loopingrecursion.com too! What's going on.
How about this?
<tr class="<%= cycle(*[["striped"]*3,["unstriped"]*3].flatten) %>">
Actually this sounds like something i would solve using pure CSS:
table tr:nth-child(6n+1), table tr:nth-child(6n+2), table tr:nth-child(6n+3) { background:red;}
table tr:nth-child(6n+4), table tr:nth-child(6n+5), table tr:nth-child(6n) { background:blue;}
While this is short and dandy, this does not work in IE unfortunately (it will work in the new IE9).
To get this working you could use jQuery, which offers the same selectors and is completely cross-browser compatible.
In your css you add two classes:
table_row_third_even { background: red;}
table_row_third_odd { background: blue;}
and then you write some javascript (inside application.js for instance), like this
$(function() {
$('table tr:nth-child(6n+1), table tr:nth-child(6n+2), table tr:nth-child(6n+3)').addClass('table_row_third_even');
$('table tr:nth-child(6n+4), table tr:nth-child(6n+5), table tr:nth-child(6n)').addClass('table_row_third_odd');
});
and your table would have to have the class highlight (you should change that to a better suiting name, this is just an example); but nothing specific for your tr tags, as they will be added by the javascript code.
<table class='highlight'>
<tr> ... </tr>
<tr> ... </tr>
<tr> ... </tr>
<tr> ... </tr>
</table>
But for this to work you would need to introduce jQuery inside your project. The good thing: it would keep your ruby-code clear from the clutter needed to do this.
Hope this helps!
I found a way to do this, which is sort of "clean" and suits me for now. Details:
In a controller helper (no error checking, yet!):
def cycle_every_third(options = [])
cycle(options[0],options[0],options[0],options[1],options[1],options[1])
end
HTML:
...
<tr class="<%= cycle_every_third(["table_row_1","table_row_2"] ) %>">
...
CSS:
.table_row_1 { background-color: red;}
.table_row_2 { background-color: blue;}
Is that a good way to go about this I wonder? Any pitfalls in Rails I may not be aware of, of calling cycle() inside a helper method as opposed to calling it in the rhtml/erb file?