Making some CSS modifications in a HAML file - ruby-on-rails

I am still new to all HAML and CSS and currentyly working on this part of a code:
- my_provider_list.each do |provider|
%li{ class: 'group_classes group-list-colspace', id: provider.name }
= provider.name
%span{class: 'group-list'}= provider.value
%span{class: 'group-list'}= provider.specialty
So I borrowed from other parts of the code we had and got it to that point seen in the picture below
But I can't figure out how to make some space between the values it shows for specialty and the cost value
What do you suggest to add or modify to get that part fixed?
Here is the generate code with html space added:
<li class='group_classes group-list-colspace' id='Physician 2679'>
Physician 2679
<span class='group-list'>218395</span>
<span class='group-list'>Pediatrics</span>
</li>
And the CSS for list items is just this:
.group-list {
float:right;
}

I would add some classes to the spans and increase the padding of one of them for example
- my_provider_list.each do |provider|
%li{ class: 'group_classes group-list-colspace', id: provider.name }
= provider.name
%span{class: 'group-list-value group-list'}= provider.value
%span{class: 'group-list-specialty group-list'}= provider.specialty
Then add some style padding to specialty
.group-list-specialty {
padding-left: 20px;
}
spans by there very nature are inline and are meant to be used inside of block elements and not to default to having any space around them. You can easily get around this with padding.
Likewise, if you are using rails consider putting the provider list into a separate partial

just add a non breakable space between them:
- my_provider_list.each do |provider|
%li{ class: 'group_classes group-list-colspace', id: provider.name }
= provider.name
%span{class: 'group-list'}= provider.value
%span{class: 'group-list'}= provider.specialty

Related

Breadcrumbs on Rails with Tailwind

I'm trying to write a custom builder to use with Breadcrumbs on Rails. I am using Tailwind for my styles but it doesn't seem to play nicely with Rails-generated code.
I have the following builder:
class TailwindBreadcrumbsBuilder < BreadcrumbsOnRails::Breadcrumbs::Builder
def render
#context.content_tag(:nav, class: 'flex py-3 px-5 text-slate-700 bg-slate-50 rounded-lg border border-slate-200', aria: { label: 'Breadcrumb' }) do
#context.content_tag(:ol, class: 'inline-flex items-center space-x-1 md:space-x-3') do
#elements.collect do |element|
render_element(element)
end.join.html_safe
end
end
end
def render_element(element)
current = #context.current_page?(compute_path(element))
aria = current ? { aria: { current: 'page' } } : {}
#context.content_tag(:li, aria) do
#context.content_tag(:div, class: 'flex items-center') do
link_or_text = #context.link_to_unless_current(compute_name(element), compute_path(element), element.options.merge(class: 'ml-1 text-sm font-medium text-slate-700 hover:text-white md:ml-2'))
divider = #context.content_tag(:span, (#options[:separator] || '>').html_safe, class: 'divider') unless current
link_or_text + (divider || '')
end
end
end
end
and I initialize the breadcrumbs on the page with:
<%= render_breadcrumbs builder: ::TailwindBreadcrumbsBuilder %>
However, not all styles are being applied (for example, the white text on hover does not work).
I suspect the Tailwind server doesn't compile these classes since they are Ruby-generated. Any idea how I can get this builder to work with Tailwind?
Thanks in advance
If you are using Tailwind v3, the classes are "purged" by default.
Since this is a ruby helper, I'd assume that this particular file was not added to the content list in tailwind.config.js.
Perhaps try adding something like this your config file:
module.exports = {
content: [
"./app/views/**/*.html.erb",
"./app/helpers/**/*.rb",
"./app/javascript/**/*.js",
"path/to/your/file.rb"
],
// ... your other configs
}
Hope that helps!

Rails Locals - Passing Connected Model Data

My model structure is pretty solid. I have MarketingDeliverySystem has_many MarketingSections. MarketingSections has_many MarketingVideos.
I have another segment: GroupDevelopment has_many GroupSections. GroupSections has_many GroupVideos.
I'm trying to use a partial to pass the variables, thus DRYing it all up.
I have the following that I'm trying to pass to the partial:
= render partial: '/sales_presentations/sales_presentation',
locals: { marketing_delivery_system: #marketing_delivery_system,
first_video: first_marketing_video(#marketing_delivery_system),
sales_presentation: #marketing_delivery_system}
Then in the partial I have the following:
.rounded-box-header.blue-bg #{sales_presentation.title}
ul
- sales_presentation.sections.ordered.each_with_index do |section, index|
- list_class = 'section show'
- list_class = 'section hide' if index != 0
li
= link_to section.title, '#', class: 'section', data: { id: section.id }
ul class="#{list_class}" data-section-id="#{section.id}"
- section.videos.ordered.each do |video|
li.video
= link_to video.title, '#',
class: 'video video-link',
data: { video: video.youtube_link,
sales_presentation: sales_presentation.title.parameterize }
.seven.columns
.row
div id="#{sales_presentation.title.parameterize}-container"
video {
id="#{sales_presentation.title.parameterize}-video-player"
class="video-js vjs-default-skin videos"
height=400
poster=""
controls preload='none'
data-default-url="#{first_video(sales_presentation)&.youtube_link}"
I previously had issues with sales_presentation.title at the top until I updated the locals.
My question/issue is how do I pass in through the locals to use for sales_presentation.sections instead to use #marketing_delivery_system.marketing.sections?
I thought I could just put that in through locals:
sales_presentation.sections: #marketing_delivery_system.marketing_sections but I end up with a massive syntax error.
I've also tried creating a partial view for these two and then changed sales_presentation throughout the view to mod. Then changed mod.sections to mod_section and setting that in the locals to mod_section: #marketing_delivery_system.marketing_section. The problem then gets into that I end up needing to hit video later in the iteration. So then that has the same issue.
You misunderstand the meaning of locals in partials.
Says we have
<%= render partial: 'image', locals: {size: #image.size, extension: #image.extension} %>
It means that in image partial now we can use local variable size and extension (keys) as #image.size and #image.extension (values).
Put in locals: {} all local variables you want.
So you can't write in locals sales_presentation.sections: #marketing_delivery_system.marketing.sections
But you can sales_presentation_sections: #marketing_delivery_system.marketing.section
Also you have problem with this code:
locals: { marketing_delivery_system: #marketing_delivery_system,
first_video: first_marketing_video(#marketing_delivery_system),
sales_presentation: #marketing_delivery_system }
marketing_delivery_system and sales_presentation will be with the same value.

data attributes in li class?

I have this code in my model:
def features_to_html_class
"mix #{bedrooms} #{region.name} #{categories.map{|cat|cat.name}.join(' ')}"
end
In my view this
- #regions.each do |region|
- #houses.where(region_id: region.id).each do |house|
%li{:class => house.features_to_html_class }
The HTML output is this:
<li class='mix 3 umbria price_range-1 villa_with_pool '>
This work fine but now i want to add data attributes "data-sort" and "data-order" to the li class. So i have this HTML output
<li class="mix 3 umbria price_range-1 villa_with_pool" data-sort="data-name" data-order="desc">
How must i change the features_to_html_class method to realize this?
Thanks...remco
To add new attributes in Haml you just have to pass them as hash ('attribute_name' => 'value')
Following should do
- #regions.each do |region|
- #houses.where(region_id: region.id).each do |house|
%li{:class => house.features_to_html_class, "data-sort" => "data-name", "data-order" => "desc"}
Edit:
Why your change in method 'features_to_html_class' can not be used in the view, because
you have directly written it class attributes(the value appended in the class of li element)
%li{:class => house.features_to_html_class }
This should work:
%li{class: house.features_to_html_class, data: {sort: 'data-name', order: 'desc'}}
Update
Since your data values are dynamic, you could change your method to provide the whole attributes hash:
def features_to_html_attributes
{
class: "mix #{bedrooms} #{region.name} #{categories.map{|cat|cat.name}.join(' ')}",
data: {sort: 'data-name', order: 'desc'}
}
end
And assign it via:
%li{features_to_html_attributes}

Override body attribute in HAML

I am currently on a Rails project and I want to override the attributes defined in the body tag in a view that is not part of the layout.
Like this:
app/views/layouts/application.haml
...header
%body
= render 'shared/menu'
.container
= yield
In another view. I want the body tag to have certain attributes:
app/views/stuff/index.haml
{data: {spy: 'scroll', target: '.d-sidebar', :'twttr-rendered' => 'true'}} << these attributes should apper in the body tag of the layout file. They should only be visible on the sub page
What is the easiest way to achieve this?
You could probably provide it:
in layout
%body{ yield(:body_attributes) }
in view
- provide(:body_attributes, { class: '', data: {} })

How can I iterate through a CSS class' subclasses?

I have a CSS file which contains several hundred 16x16 icons. They are referenced using a CSS class/subclass arrangement, like so:
<span class="icons icon_name"></span>
So, if I need an "arrow up" icon, I simply code:
<span class="icons arrow_up"></span>
And so on. Because there are so many icons in the library, I created a reference page (in Haml), so I could quickly find which icon I need. An example of the Haml code:
%div.icons.arrow_turn_right
arrow_turn_right
%br
%div.icons.arrow_undo
arrow_undo
%br
%div.icons.arrow_up
ss_arrow_up
%br
It occurs to me that this is a rather brute force method to writing the page. 300 icons require nearly 1000 lines of code.
My question: Is there a way to iterate through a CSS class' subclasses using an each loop (or something similar)?
Something like this:
subs = mainCSSclass.allSubclasses <--Replace this line with functional code
subs.each do |subclass|
... display the |subclass| ...
end
Is such a thing possible?
Edit: Here is a partial of the actual CSS file being referenced:
.icons {
display: inline;
overflow: hidden;
height: 16px;
padding-left: 18px;
background: url(icons.png) no-repeat;
}
.accept {
background-position: 0px 0px;
}
.add {
background-position: 0px -19px;
}
.anchor {
background-position: 0px -37px;
}
.application {
background-position: 0px -55px;
}
.application_add {
background-position: 0px -73px;
}
.application_cascade {
background-position: 0px -91px;
}
Solution (thanks to #Corroded's answer):
In my pages_helper.rb:
def read_css_cfg
css_classes = Array.new
file = File.new("public/stylesheets/blueprint/plugins/icons/icons.css", "r")
while line = file.gets
parsed = line.scan(/[.]\w+ {/).to_s.scan(/\w/).join
css_classes << parsed if !parsed.blank?
end
file.close
css_classes
end
In my actual Haml file:
- parse = read_css_cfg
- parse.delete("icons") #unrelated class, but in the same file'
- column = 1
.container
- parse.each do |class_name|
- case column
- when 1
<div class = "css_row">
%div{:class => "icons #{class_name} three_column"}
#{class_name}
- column += 1
- when 2
%div{:class => "icons #{class_name} three_column"}
#{class_name}
- column += 1
- when 3
%div{:class => "icons #{class_name} three_column"}
#{class_name}
</div>
- column = 1
Finally, though this has nothing to do with the original question, my final answer contained code which auto-generated a 3-column "div-table." If you're interested in the CSS to use DIV's instead of a table, here it is:
.container {
display: table;
width: 675px;
}
.three_column {
display: table-cell;
width: 225px;
}
.css_row {
display: table-row;
Okay, so basically, the plan is to loop through all those classes and generate them in a Haml page, right?
What I would do is open that CSS file (using Ruby of course) and then use a regular expression to parse and get all the subclasses. Since you would want to call that in a view, then I suggest using a helper:
def loadCSSClasses
cssClasses = []
cssFile = File.open("yourcssfile.css") do
#Forgive me, my regular expression is weak, but basically you would want to get all the classnames after the word ".icon."
cssClasses << className
end
cssClasses
end
Then in your Haml file do this:
%ul
- loadCSSClasses.each do |class_name|
%li{:class => "icon #{class_name}"
= "ss_#{class_name}"

Resources