Selectively using yield_content in Padrino application.haml template - ruby

In a Haml based Padrino solution I have an application.haml like this:
!!!
%html
%head
%title "blah"
%body
#header
= yield_content :headcontent
#container
...
For :headcontent, in my page (e.g. index.haml) I have
- content_for :headcontent do
#headcontent
%h2= "Index header stuff"
#content
...
What I want to do is make it so that content pages like index.haml can optionally specify - content for :headcontent. That is I want application.haml to contain some default :headcontent that only is rendered if a page does not do - content for :headcontent.
How do I do this?

In your main file, you should be able to use content_for?, like this:
- if content_for?(:headcontent)
= yield_content :headcontent
- else
something else

Related

How to output data from Yaml variables (written in markdown) into an HTML Haml file?

In a Yaml data file aaa.yml I have:
yyy: |
[foo](http://example.com) bar.
I want to pull this data from a Haml file (zzz.html.haml).
1. If I do zzz.html.haml:
%p
= data.aaa.yyy
Middleman renders zzz.html:
<p> [foo](http://example.com) bar</p>
2. If I do:
%p
:markdown
= data.aaa.yyy
Middleman renders:
<p>= data.aaa.yyy</p>
How can I make it render:
<p>foo bar</p>
?
You have a string that contains markdown, and you want to render that markdown and include the result in your output.
One way would be to use the Haml :markdown filter. You can’t use normal Haml syntax inside a filter (like you’ve tried), but you can use interpolation inside #{...}, so you could do
:markdown
#{data.aaa.yyy}
A better way, if the string is a standalone chunk, might be to create a helper method that renders markdown, and call that.
Wherever you have your helpers add something like:
def markdown s
# I'm using kramdown here, but you can use whatever processor you prefer.
Kramdown::Document.new(s).to_html
end
Then in your Haml:
= markdown(data.aaa.yyy)
Yay! Turns out there's this helper, which was already in my config.rb but didn't work by itself:
def markdown(text)
Tilt['markdown'].new { text }.render
end
When I installed this helper (from #matt's answer) with the first one:
def markdown s
Kramdown::Document.new(s).to_html
end
Then = markdown(foo.bar) worked, which made my day!! :D

How to rendering partials within a partials in middleman

I have some Haml partials, many of which contain the boilerplate
.container
.row
.col-lg-12
When I try to abstract that out ala = partial "site_section", I get:
syntax error, unexpected keyword_end, expecting end-of-input end;end;end;end
I'm using ruby 2.2.2.
How do I render a Haml partial within a Haml partial in Middleman?
Thanks
update
This is apparently some kind of special case dealing with my partial (above). I have other partials-within-partials rendering just fine.
update
With respect to this this repo, the layout would actually be:
_site_section:
.container
.row
.col-lg-12
_nested_section:
= partial "site_section"
MOAR (nested) HAML
index.haml:
=partial "nested_section"
Because of the way HAML works the following is invalid:
= partial "site_section"
MOAR (nested) HAML
If you want to add more text or HAML then you can achieve it for example by putting the text at the same level of the previous line
= partial "site_section"
MOAR (nested) HAML
Or nesting it within a div:
= partial "site_section"
.more
MOAR (nested) HAML
So If what you are trying to do is to nest extra HAML to the output of the site_section partial, then you have to put the nested extra HAML in the nested partial:
.container
.row
.col-lg-12
= partial 'nested_stuff'
= partial 'nested_stuff'
Hope this helps, I updated the repo with the working example.

RDiscount :generate_toc with Sinatra

So I have sinatra setup with Rdiscount to render a markdown file with a HAML layout. This all works but I want RDiscount to generate a table of contents based on the headers in my haml file. I've tried setting it in the sinatra configuration.
set :markdown, :generate_toc => true
but that doesn't seem to work.
I've also tried doing it when I render the markdown like so:
markdown :PAGENAMEHERE, :layout => :'layouts/PAGENAMEHERE', :generate_toc => true
which also doesn't work.
Is this even possible? If it is, what am I doing wrong?
While #three's answer helped me a lot, I would like to show a perhaps more general solution:
class MDWithTOC < ::Tilt::RDiscountTemplate
def flags
[:generate_toc]
end
end
Tilt.register MDWithTOC, 'md'
Here we override the flags method of the RDiscount Tilt template handler and regiter it as a handler for the md format.
Now you can use the md helper as always and it will generate the TOC.
This should work:
get '/' do
text = File.read('README.md')
markdown = RDiscount.new(text, :generate_toc)
body = markdown.to_html
haml :home, :layout => true, :locals => {:body => body}
end
You create the body directly via RDiscount and include it as plain HTML in your HAML layout. Whatever prevented toc creation should work this way natively. I found the solution via https://github.com/mjijackson/markdown/blob/master/app.rb

Cannot iterate through array in Slim's logic

I am trying to iterate through an array named #items. I thought by adding it to a class variable and calling it from SLIM I might be able to output the array. What am I doing wrong?
require "rubygems"
require "sinatra"
require "slim"
set :port, 80
get "/" do
slim :index
end
get "/history" do
#items = Dir.entries(File.expand_path(File.dirname(__FILE__)) + "/history").to_a
slim :history
end
__END__
##layout
doctype html
html
head
title Web View
body
div id="main" name="main"
h1 Web View
== yield
##index
h2 Available Options
a href="/history" id="history_view" name="history_view" History
##history
h2 History
- unless items.empty?
- for item in items do
a href="#{item}/output.html" item
- else
p NO ITEMS FOUND
It seems that you've tried to call items method in your 'history' layout. Besides this look at indentation level for your else clause. Try to change your code:
h2 History
- unless #items.empty?
- for item in #items do
a href="#{item}/output.html" item
- else
p NO ITEMS FOUND

How to structure a layout template in Haml

I have a web page that uses Haml for layouts. "layout.haml" is a separate layout file which is used when rendering any actual Haml page.
layout.haml looks something like:
-# layout.haml
!!! XML
!!!
%html
%head
...
%body
...
#content= yield
This is of course already in the document's <body> so manipulating things in the header is not directly possible. For instance <title> is changed via #title. A bigger problem is the fact that every page-specific JavaScript needs to be loaded in the body. Moreover, layout.haml already contains JavaScript, so jQuery is usually instantiated multiple times.
Are there any suggestions for a better template structure?
This solution is for Ruby on Rails only:
You can use yield(:location) and the content_for(:location) methods. "Using the content_for Method" has more information.
layout.haml:
!!!
%html
%head
%title= yield(:title)
= yield(:head)
%body
= yield
view.haml:
- content_for(:title, 'My title')
- content_for(:head) do
= javascript_include_tag :foo
%h1 My view!
I use partials:
!!!
%html
= partial('trst_sys/shared/html-head')
%body{:id => "srv",:'data-lang' => current_lang}
#main.wrap
%header#header
= partial('trst_sys/shared/header')
%nav#menu
= partial('trst_sys/shared/menu')
%section#content
%article#xhr_content
= yield
%article#xhr_msg.hidden
%section#sidebar
= partial('trst_sys/shared/sidebar')
%section#main_footer.wrap
%footer#footer.wrap
= partial('trst_sys/shared/footer')

Resources