Where can I use HAML in Octopress? - ruby

So, according to the Octopress official page, it has HAML integration plugin. Naturally, I gave it a try. I backed up my source/_includes/custom/head.html file, converted it to haml and saved it as source/_includes/custom/head.haml. It gave me an error.
I tried doing the same with source/_layouts/page.html file, and it worked like a charm.
My question is, where can I and where can I not use HAML in an Octopress blog?

AS you can see from the source code, the HAML is only processing pages content.
See the convert && output_ext methods.
https://github.com/imathis/octopress/blob/master/plugins/haml.rb
module Jekyll
require 'haml'
class HamlConverter < Converter
safe true
priority :low
def matches(ext)
ext =~ /haml/i
end
def output_ext(ext)
".html"
end
def convert(content)
begin
engine = Haml::Engine.new(content)
engine.render
rescue StandardError => e
puts "!!! HAML Error: " + e.message
end
end
end
end

Related

How to upgrade redmine plugin to rails 5, alias_method_chain is deprecated now

Story mode
Just started learning RoR, but in short period of time I need to add functionality similar to Loading images from LDAP (incompatible version) into our project. Project is abondoned, and I can't find any related info/docs, so I'm asking for help here. Solution, tutorial, anything could work.
Error log
$ ruby bin/rake redmine:plugins RAILS_ENV="production"
rake aborted!
NoMethodError: undefined method `alias_method_chain' for ApplicationHelper:Module
Did you mean? alias_method
...
Monkey patch that needs update
plugins\redmine_gemavatar\lib\application_helper_gemavatar_patch.rb :
require 'application_helper'
module GemAvatarPlugin
module ApplicationAvatarPatch
def self.included(base)
base.send(:include, InstanceMethods)
base.class_eval do
alias_method_chain :avatar, :gemavatar
end
end
module InstanceMethods
def avatar_with_gemavatar(user, options = { })
if Setting.gravatar_enabled? && user.is_a?(User)
options.merge!({:ssl => (defined?(request) && request.ssl?), :default => Setting.gravatar_default})
options[:size] = "64" unless options[:size]
avatar_url = url_for :controller => :pictures, :action => :delete, :user_id => user
return "<img class=\"gravatar\" width=\"#{options[:size]}\" height=\"#{options[:size]}\" src=\"#{avatar_url}\" />".html_safe
else
''
end
end
end
end
end
My attempts / Articles
I've found good article here How To Replace alias_method_chain, but I'm not quite sure how to apply prepend style to redmine plugin's monkey patch. Just can't get it work :/
Is this related to this plugin?
If so, here is how I would do it:
In the init.rb file, change this:
RedmineApp::Application.config.after_initialize do
ApplicationHelper.send(:include, GemAvatarPlugin::ApplicationAvatarPatch)
end
To this:
RedmineApp::Application.config.after_initialize do
ApplicationHelper.prepend(GemAvatarPlugin::ApplicationAvatarPatch)
end
In lib/application_helper_gemavatar_patch.rb, change this:
require 'application_helper'
module GemAvatarPlugin
module ApplicationAvatarPatch
def self.included(base)
base.send(:include, InstanceMethods)
base.class_eval do
alias_method_chain :avatar, :gemavatar
end
end
module InstanceMethods
def avatar_with_gemavatar(user, options = { })
# method content omitted for clarity
end
end
end
end
to this:
module GemAvatarPlugin
module ApplicationAvatarPatch
def avatar(user, options = { })
# method content omitted for clarity
end
end
end
I would remove the require 'application_helper' because I don't see why it's needed
I also tried to update this plugin. I used https://github.com/alexandermeindl/redmine_local_avatars as an example.
In init.rb changed this:
RedmineApp::Application.config.after_initialize do
ApplicationHelper.send(:include, GemAvatarPlugin::ApplicationAvatarPatch)
end
to this:
RedmineApp::Application.config.after_initialize do
ApplicationHelper.include ApplicationAvatarPatch
end
the patched lib/application_helper_gemavatar_patch.rb, looks like this:
module ApplicationAvatarPatch
def self.included(base)
base.send(:include, InstanceMethods)
base.class_eval do
alias_method :avatar_without_gemavatar, :avatar
alias_method :avatar, :avatar_with_gemavatar
end
end
module InstanceMethods
def avatar_with_gemavatar(user, options = { })
if Setting.gravatar_enabled? && user.is_a?(User)
options.merge!({:ssl => (defined?(request) && request.ssl?), :default => Setting.gravatar_default})
options[:size] = "64" unless options[:size]
avatar_url = url_for :controller => :pictures, :action => :delete, :user_id => user
return "<img class=\"gravatar\" width=\"#{options[:size]}\" height=\"#{options[:size]}\" src=\"#{avatar_url}\" alt=\"Gemavatar text\" />".html_safe
else
avatar_without_gemavatar(user, options)
end
end
end
end
I tried it only with Redmine 4.0.3 but it seems to be working. However there are warnings in the webserver log:
127.0.0.1 - - [06/Mar/2020:20:58:23 CET] "GET /gemavatar/164 HTTP/1.1" 200 3545
http://tredmine1:3000/users/164 -> /gemavatar/164
[2020-03-06 20:58:23] WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
In the redmine_local_avatars plugin there was a different patch for Redmine 4.1.
Update: I set a up a github repository with the changes: https://github.com/pentekl/redmine_gemavatar
You can use alias_method instead of alias_method_chain, but I'm searching for something like prepend solution
alias_method :avatar_without_gemavatar, :avatar
alias_method :avatar, :avatar_with_gemavatar
UPD:
But it throws warnings:
/app/helpers/application_helper.rb:180: warning: already initialized constant ApplicationHelper
::RECORD_LINK
/app/helpers/application_helper.rb:180: warning: previous definition of RECORD_LINK was here
/app/helpers/application_helper.rb:199: warning: already initialized constant ApplicationHelper
::ATTACHMENT_CONTAINER_LINK
/app/helpers/application_helper.rb:199: warning: previous definition of ATTACHMENT_CONTAINER_LI
NK was here
/app/helpers/application_helper.rb:1053: warning: already initialized constant ApplicationHelpe
r::LINKS_RE
/app/helpers/application_helper.rb:1053: warning: previous definition of LINKS_RE was here
Exiting
UPD:
As ste26054 mentioned in his answer and commented here
require 'application_helper' can be deleted to prevent warnings, since it already included in the core.

how to pass content to jekyll default converter after custom conversion?

I am trying to write a jekyll plugin which do something on markdown files first and passing the content back to the default converter
For example,
module Jekyll
class RMarkdownConverter < Converter
safe :false
priority :high
def matches(ext)
ext =~ /^\.(md|markdown)$/i
end
def output_ext(ext)
".html"
end
def convert(content)
# do something with content
# then pass it back to default converter
end
end
end
Right now, the closest thing that I could get it
converter = Jekyll::Converters::Markdown::KramdownParser.new(#config)
converter.convert(content)
But all the highlighting codes are losing color...and I suspect there are other problems...
My question is:
what is a correct way to invoke the default converter?
Here's how to do it:
module Jekyll
class MyConverter < Converter
safe :false
priority :high
def matches(ext)
ext =~ /^\.(md|markdown)$/i
end
def output_ext(ext)
".html"
end
def convert(content)
# do your own thing with the content
content = my_own_thing(content)
# Now call the standard Markdown converter
site = Jekyll::Site.new(#config)
mkconverter = site.getConverterImpl(Jekyll::Converters::Markdown)
mkconverter.convert(content)
end
end
end
Basically, you were right in using Jekyll::Converters::Markdown, but you need not specify KramdownParser, as your chosen parser will be automatically chosen from Jekyll::Site when you pass #config into the constructor.

ActionMailer : Render multipart emails (text/html) from markdown the correct way?

I would like to render all my emails from markdown with using a layout "email".
Have been investigating gems and options there are 2 gems I could both could not get to work:
maildown and markerb.
Has anyone implemented a method to render text,html emails with action mailer from a markdown mail template and also using a layout? Or knows a good updated writeup on this?
Markerb registers a .markerb file extension like so:
module Markerb
class Railtie < ::Rails::Railtie
config.markerb = Markerb
config.app_generators.mailer :template_engine => :markerb
end
end
and
require "redcarpet"
require "markerb/railtie"
module Markerb
mattr_accessor :processing_options, :renderer
##processing_options = {}
##renderer = Redcarpet::Render::HTML
class Handler
def erb_handler
#erb_handler ||= ActionView::Template.registered_template_handler(:erb)
end
def call(template)
compiled_source = erb_handler.call(template)
if template.formats.include?(:html)
"Redcarpet::Markdown.new(Markerb.renderer, Markerb.processing_options).render(begin;#{compiled_source};end).html_safe"
else
compiled_source
end
end
end
end
ActionView::Template.register_template_handler :markerb, Markerb::Handler.new

What are the steps to getting this 'custom' permalink scheme in Jekyll?

I'm writing a Jekyll setup and I'd like to get my posts to have a permalink in the form: /2013/jan/something-something-in-january. I understand that it is impossible with vanilla permalinks to:
get the :month to be in text form or
get the :title to be dash delimited
I remember reading somewhere that I could achieve this by writing a plugin, but I'm not sure how. How can I do this?
I created a generator plugin:
module Jekyll
class PermalinkRewriter < Generator
safe true
priority :low
def generate(site)
# Until Jekyll allows me to use :slug, I have to resort to this
site.posts.each do |item|
item.data['permalink'] = '/' + item.slug + '/'
end
end
end
end

Can't get page data from Jekyll plugin

I'm trying to write a custom tag plugin for Jekyll that will output a hierarchical navigation tree of all the pages (not posts) on the site. I'm basically wanting a bunch nested <ul>'s with links (with the page title as the link text) to the pages with the current page noted by a certain CSS class.
I'm very inexperienced with ruby. I'm a PHP guy.
I figured I'd start just by trying to iterate through all the pages and output a one-dimensional list just to make sure I could at least do that. Here's what I have so far:
module Jekyll
class NavTree < Liquid::Tag
def initialize(tag_name, text, tokens)
super
end
def render(context)
site = context.registers[:site]
output = '<ul>'
site.pages.each do |page|
output += '<li>'+page.title+'</li>'
end
output += '<ul>'
output
end
end
end
Liquid::Template.register_tag('nav_tree', Jekyll::NavTree)
And I'm inserting it into my liquid template via {% nav_tree %}.
The problem is that the page variable in the code above doesn't have all the data that you'd expect. page.title is undefined and page.url is just the basename with a forward slash in front of it (e.g. for /a/b/c.html, it's just giving me /c.html).
What am I doing wrong?
Side note: I already tried doing this with pure Liquid markup, and I eventually gave up. I can easily iterate through site.pages just fine with Liquid, but I couldn't figure out a way to appropriately nest the lists.
Try:
module Jekyll
# Add accessor for directory
class Page
attr_reader :dir
end
class NavTree < Liquid::Tag
def initialize(tag_name, text, tokens)
super
end
def render(context)
site = context.registers[:site]
output = '<ul>'
site.pages.each do |page|
output += '<li>'+(page.data['title'] || page.url) +'</li>'
end
output += '<ul>'
output
end
end
end
Liquid::Template.register_tag('nav_tree', Jekyll::NavTree)
page.title is not always defined (example: atom.xml). You have to check if it is defined. Then you can take page.name or not process the entry...
def render(context)
site = context.registers[:site]
output = '<ul>'
site.pages.each do |page|
unless page.data['title'].nil?
t = page.data['title']
else
t = page.name
end
output += "<li>'+t+'</li>"
end
output += '<ul>'
output
end
Recently I faced a similar problem where the error "cannot convert nill into string" is just blowing my head. My config.yml file holds a line something like this " baseurl: /paradocs/jekyll/out/ " now thats for my local for a server i need to make that beseurl empty and the error starts to appear in build time so finally i have to made " baseurl: / " .. And that's did my job.

Resources