Tilt (kramdown) preventing ERB processing during rendering

I am creating a website with Middleman . I store a lot of information in data files as I am going to use the same information across multiple pages. (Partials won't work for me, as the same text from data can be used with different HTML tags, or vary slightly for different pages.)

I want to write markdown in data files and then use it in HAML templates for specific pages. When I try to create relative links to other pages when using a link to another data file, the resulting HTML is not what it should be.

data/pages.yaml

:

pageA:
  link: /it-can-change-A.html
  name: PageA name
  info: Some other related info

pageB:
  link: /subject-to-change-B.html
  name: PageB name
  info: Some other related info

pageC:
  link: /some-C.html
  name: PageC name
  info: Some other related info

      

data/faq.yaml

:

testcase: Some text with [internal link to page A](ref.pageA). And *another* [internal reference](ref.pageB).

verbatim: Some text with [internal link to page A](/it-can-change-A.html). And *another* [internal reference](/subject-to-change-B.html).

      

While trying to find the root cause of this problem, I tested various ways to "extract" relative references from a data file and put them in a HAML template. My ultimate goal is to make case (5) work.

I have commented out the results of each piece of code directly in test.html.md.erb.haml

:

Note that HAML must be processed before ERB, so .haml must be the last extension. If placements have .erb and .haml extensions, then in case (3) and (4) below, a different output will be given.

/ Pure ERB; ERB is processed before markdown => :)
(1) This is just some text with [ERB link to first page](<%= data.pages.pageA.link %>) and *another* one [to second page](<%= data.pages.pageB.link %>). 

/ ERB inside HAML tag; markdown is not processed => :|
.haml
    (2) This is just some text with [ERB link to first page](<%= data.pages.pageA.link %>) and *another* one [to second page](<%= data.pages.pageB.link %>). 

/ Helper used WITHOUT a tag; ERB is processed before markdown => :)
(3)
= refonly(data.faq.testcase) 

/ Helper used WITH a tag; ERB is processed, but markdown is not => :|
.question1
    (4)
    = refonly(data.faq.testcase)

/ "Tilt-powered" helper used WITHIN a tag; trying to process markdown with Tilt results in "%=%20data.pages.pageA.link%20%" links. Expected behavior: ERB should be processed first, then Tilt should process markdown with actual relative links being the same as in .question1 above => :(
.question2
    (5)
    = mymarkdown(data.faq.testcase)

/ Helper with Tilt to process verbatim text; markdown is processed correctly => :)
.question3
    (6)
    = justmarkdown(data.faq.verbatim)

      

The helpers used in the template above:

def refonly(text)
    text.gsub(/ref\.(page[A-Z])/,"<\%= data.pages.\\1.link %>")
end

def mymarkdown(text)
    newtext = refonly(text)
    Tilt['markdown'].new(context: @app) { newtext }.render
end

def justmarkdown(text)
    Tilt['markdown'].new(context: @app) { text }.render
end

      

The goal of the first helper is to change the easy-to-write reference inside the data file (ref.pageName) to ERB code the same as in (1). The goal of the second helper is to markdown in case .md

the template extension itself cannot automatically render it. The purpose of the last helper is to show that Tilt can correctly display text in text (6), but when it accepts the same text as a variable, it cannot produce the same output in (5).

and. When I use a "pure ERB" (1) or refonly

no HAML tag helper (3), the output looks as expected: the relative path is fetched from the data file, and then the markdown is handled by default using a markup engine (kramdown) thanks to .md

the template extension.

Q. When I try to use the HAML tag, either directly with the ERB code (2) or using the refonly

helper (4), the ERB is processed correctly and placed in the output file. However, the markdown is not automatically processed for some reason, although the expansion is .md

used immediately after .html

, so the markdown must be processed after the HAML and ERB bits are completed.

C. To "force" the markdown rendering, I use Tilt in my second helper. My intention was to pass the text returned refonly

(which has the correct markup syntax, with the intended link fetched from the data) to Tilt. My guess was that Tilt would simply transmit the verbatim text given to it in (5), just like in (6). Instead, the resulting link points to %=%20data.pages.pageA.link%20%

which appears to be HTML rendering the ERB code verbatim. So it looks like passing a variable newtext

to Tilt somehow stops ERB processing, and the ERB code is passed directly to markdown.

My main question is, how can I make sure Tilt is getting the correct text with a relative link (how is it returned refonly

) and producing the expected result in (5)? In the meantime, there is no need to know about it. ”

My secondary question is, why is markdown not automatically handled by Middleman in the cases described in section B.?

I guess the answer to my main question requires knowledge of Ruby and Tilt, while the answer to my secondary question requires knowledge of Middleman. While a solution to my main problem would be great, answering a secondary question might allow you to skip Tilt altogether and therefore solve the problem in an easier way.

+1


source to share


1 answer


Since you are already parsing the HAML correctly, and when you are processing verbatim links it works, try using a helper to inject links directly without going into the ERB. Since HAML is already running Ruby code, I don't see the need to pass it through the ERB. I think that eval

will allow you to get the same effect with which you use ERB. Something like that:

def refonly(text)
  text.scan(/ref\.(page[A-Z])/).each do |groups|
    page_name = groups[0]
    text.gsub!(/ref\.#{page_name}/, eval("data.pages.#{page_name}.link"))
  end
  text
end

      



EDIT. Scanning the text will allow you to get each page name so you can scroll through each one and replace the link on each link with a link.

+1


source







All Articles