In a list of blog posts that has been truncated, I prefer if the the ”Read more”-link only appears when there actually is more to read.
Also, after clicking a read more-link, I prefer if the page scrolls up, making it easy to continue reading.
I’ve added some code to config.rb to do this. It’s a workaround, not very elegant. But I suspect that this kind of functionality will be added to the blog extension in the future, so this will do for the time being.
Workaround to automaticly add ‘Read more’-links
The blog extension has functions for extracting a summary from an article, either by looking for a manually added separator, or after a certain number of characters.
It will however not automatically generate a read more-link. For this some working around is required.
Do do this, we will utilize that the summary function will accept a custom summary generator. Unfortunally, it is only applied when generating a summary of a certain size. If the separator is manually added, it will be taken care of before reaching the generator.
But by adding a dummy separator, that never exist in any text, to the blog preferences we can make all articles go to the generator.
As a first step, we define the separator pattern in config.rb
@readmore_separator = /(<p>)?\(Read more\)(<\/p>)?/i
This will look for a ”(Read more)” separator (it will be used both in the blog options and further down in config in the helper section, by the cleanup_readmore function.)
Then we define the generator. (separator
is the separator pattern, readmore_text
is the text of the link to the full article, and if link_to_separator_position
is true, the page will scroll up, making it easy to find where to continue reading)
def setup_summary_generator(
separator = /(READMORE)/i,
readmore_text = 'Read more',
link_to_separator_position = true)
return Proc.new do |resource, rendered, length, ellipsis|
require 'middleman-blog/truncate_html'
if link_to_separator_position
readmore_link = "\n<p class = 'readmore'>#{link_to(readmore_text, resource, :fragment => 'readmore')}</p>"
else
readmore_link = "\n<p class = 'readmore'>#{link_to(readmore_text, resource)}</p>"
end
if rendered =~ separator
# The separator is found in the text
summary = rendered.split(separator).first
summary + readmore_link # return
elsif length
summary = TruncateHTML.truncate_html(rendered, length, ellipsis)
unless summary.strip == rendered.strip # If the
# original text was longer then the summary...
summary = summary + readmore_link # ...add
# a read more-link.
end
summary # return
else
rendered # return
end
end
end
Now we add some blog options
activate :blog do |blog|
...
blog.summary_separator = /DUMMY SEPARATOR/
blog.summary_length = 250
blog.summary_generator = setup_summary_generator(@readmore_separator)
...
end
Normally, the blog extension would remove the separator from the text. But this workaround unfortunately has worked itself around that. So in the helper section of config.rb
we need to add a function
def cleanup_readmore(html)
html.sub(@readmore_separator, "<span id='readmore'></span>")
end
and use it in the layout. Replace
yield
with
cleanup_readmore(yield)