Headings,
I prefer to write them like that, as a proper heading instead of just an item among others in the frontmatter. But i still want them to be used as the page’s <title>
To fix that the two functions below can be added to config.rb. Then add <%= pagetitle %>
or %title= pagetitle
in the layout.erb or layout.haml.
If there is a title:
in the frontmatter it will be used – as usual. But if it is missing the first h1 heading on the page will be used instead.
Since the title is not actually added to the sitemap resource, this will not work with stuff that needs it there. I have not tested it with the blogging extension.
# Get the title/main heading of the page
#
# Useful when constructing the <title> of the page.
#
# If there is a title in the frontmatter, that will be used.
# Otherwise, will search for the first h1-heading, and use that.
#
# The title can be dynamic if collected from the heading, so erb/haml can be used.
# Example: <h1>Articles for <%= year %></h1>
#
# Limitations:
# This seams to be a rather expensive operation, so when listing lots of articles it will take noticeable time.
# Maybe the result should be cached, possibly in sitemap. I've made a first try at it, but unsuccessfully.
# I'll have to learn more about the sitemap to get it to work.
#
# @param [Middleman::Sitemap::Resource] page_to_get_title_from The page that you want the title from
# @return [String] The title or h1 of the page
#
def title(page_to_get_title_from = current_page)
if page_to_get_title_from.data.title
# The title is in the metadata
page_to_get_title_from.data.title # Return
else
# No title in metadata, using the first h1 from the content
content = page_to_get_title_from.render({:layout => false}) # Renders the <body>-part to html
# (Note: at first I tried just .render(), but since that includes the title, it became an endless loop)
match = content.match(/<h1>(.*?)<\/h1>/) # Search for first h1
if match
# Caching the result – Not implemented
# This did not do the trick: page_to_get_title_from.add_metadata({:page => {'title' => escape_html(match[1])}})
return escape_html(match[1])
else
nil # Return text of first h1, or nil if none found
end
end
end
# Produces a text suitable to put in the <title> tag of the page
#
# Use in layout.erb like this: <title><%= pagetitle %></title>
# In layout.haml: %title= pagetitle
#
# You can provide your own sitename or use the site's directory name.
#
# Note: Amicus defines a 'page-title', that does a similar thing.
#
# @return [String] A text suitable to put in the <title> tag of the page
def pagetitle
# Sitename
sitename = 'anvandbart.se' # Provide your own name here. Other options: :directory_name and :none
if sitename == :directory_name
sitename = Pathname.new(current_page.app.root_path).basename.to_s # Uses the name of the sites directory
end
# Combine with title
title_from_page = title
if title_from_page
if sitename == :none
return title_from_page
else
return "#{title_from_page} | #{sitename}"
end
else
# No title:-metadata or h1 title existed in the page
if sitename == :none
return '' # Keep empty or change to whatever you prefer, for example 'Middleman'
else
return sitename
end
end
end