Middleman: url link stored in datafile from markdown

For my Middleman-built website, I have saved links and other information about all pages in a data file .

data/pages.yaml

:

pageA:
  link: /some-long-url-subject-to-change.html
  name: PageA name
  info: Some other related info

      

Then in my HAML ( source/test.haml

) template, I can print the relative path to pageA with = data.pages.pageA.link

.

Now I want to use markdown syntax to link to this page by its name (page A).

Example ( source/test.html.haml

):

.info
    :markdown
        This is some text with a [manual link](https://google.com) to somewhere. 
        This is another text with a [data-referenced link](pageA) to that page.

      

Just like the first "Manual Link" link on Google, I would like the second link to use the relative path stored in the data file to generate the link. One solution I see to solve this problem would be to replace the text (pageA)

with a mark = data.pages.pageA.link

before it is markdown displayed.

I guess it would be possible by creating a custom helper, but I cannot completely fake it.


My attempt at a solution

I tried to write my own helper to replace the text (pageA)

with the mark = data.pages.pageA.link

before it is rendered with markdown.

I was able to replace certain text ( pageA

) with information from the data, and I was also able to write a more general case that replaces all data references with the explicit text of a typical data reference. But I cannot replace data.pages.pageA.link

in the general case for evaluation = data.pages.pageA.link

.

My helper:

# Replace specific text with information from ``data/pages.yaml``
specific = text.gsub("pageA",data.pages.pageA.link)
# Generic case: using explicit text
generic = text.gsub(/\]\((.*?)\)/,'](data.pages.\1.link)')
# Generic case: trying to use variable name, but getting explicit text
generic = text.gsub(/\]\((.*?)\)/,'](#{data.pages.\1.link})')

      

Using a helper in mine test.html.haml

:

= myhelper("This is another text with a [data-referenced link](pageA) to that page.")

      

Printing the variable specific

gives me what I want ( /some-long-url-subject-to-change.html

). But when printed, the generic

variable is obtained as plain text instead of information from the data file.

It is possible that I am missing some basic knowledge and the Ruby solution is really very simple.

+3


source to share


2 answers


It looks like you are trying to write your own templating system, which is probably not the best idea. First, you need to write a regular expression that parses Markdown correctly and finds the link. Then you need to evaluate the row you pulled in to get the value from your data. Finally, you will need to replace the placeholder with this value. I more or less figured out what works with this code in config.rb:

helpers do
  def myhelper(text)
    page=/\]\((.*?)\)/.match(text)[1]
    link=eval( "data.pages.#{page}.link" )
    text.gsub(page,link)
  end
end

      

But please don't use this code! It is fragile and error prone. Even worse, there is a much easier way to do what you are trying to do. Replace test.haml test.haml.erb:

.info
    :markdown
        This is some text with a [manual link](https://google.com) to somewhere. 
        This is another text with a [data-referenced link](<%= data.pages.pageA.link %>) to that page.

= myhelper("This is another text with a [data-referenced link](pageA) to that page.")

      

The .erb extension tells Middleman to treat the file as an ERB template . In particular, it will evaluate anything in between <%=

and %>

as Ruby code. This means that you can skip using the messy helper method. As a bonus, you don't have to write more code to get other bits of data:



  • <%= data.pages.pageA.name %>

    => 'PageA name'
  • <%= data.pages.pageA.info %>

    => 'Some other related information'

If you need to do more complex processing, like iterating over a list, you can do it right in the template itself. It's easier to read and maintain this path.

I've also included a helper method call as a contrast. It is much less clear what is going on than just using the existing templating system. Also, you must forget to wrap all the relevant lines in the method and end up breaking links along the way.

As Adam suggested , you might even be better off using Markdown directly and skipping Haml .

+1


source


I'm not sure what you are meeting here. The following works on my end:

Assuming your data file data/pages.yaml

contains

pageA:
  link: /some-long-url-subject-to-change.html
  name: PageA name
  info: Some other related info

      

and your template test.haml.md.erb

looks like

---
title: Test
---

This is another text with a [<%= data.pages.pageA.name %>](<%= data.pages.pageA.link %>) to that page.

      



the output should be as follows: the page name is the clicks link.

This is a different text with the name of the page on this page.

It seems that you are having trouble interpreting the markdown. Try changing the template file name from test.haml

to test.haml.md.erb

.

This construct tells Middleman to interpret the ERB bits first, then the Markdown bits, and finally HAML (or plain HTML if it doesn't use HAML).

+1


source







All Articles