Load plain/markdown text (.txt/.md) files in Middleman - ruby

Middleman automatically loads the contents of .json or .yml data files that exist in the /data folder.
Is there any way to load the contents of any .txt or .md file inside this folder?
I found this extension, but I don't see how I can achieve that.
Example
Given this structure and the following files:
data/
├── foo.yml
└── bar.txt
foo.yml:
text: "I can load this text."
bar.txt
I want to load this text.
I can access data.foo.text and retrieve I can load this text.
I want to access data.bar and retrieve I want to load this text.

i'm not sure what you're trying to achieve by reading the txt data (or markdown). middleman data is not intended to contain data other than array/hash form. assuming you want to load long (or formatted) text, this is better way IMO
posts.yml:
-
title: First Post
file: foo.txt
-
title: Second Title
file: bar.txt
and in your view:
<% data.posts.each do |post| %>
<%= post[:title] %>
<%= simple_format(File.read("data/#{post[:file]}").html_safe) %>
<% end %>

I found a workaround until I figure out how to write my own extension for loading plain text files.
Having the following data file:
data/bar.yml:
---
title: bar
# Content in plain text can be placed after ---
---
## H2 test
- Hello __world__!
And then the content can be accessed with data.bar.postscript:
<div class="container">
<h1><%= data.bar.title %></h1>
<%= makrdown data.bar.postscript %> # In this case, I want to render it in Markdown
</div>
For rendering the Markdown I defined a helper function in config.rb:
helpers do
def markdown(text=nil)
text ||= yield
return Redcarpet::Markdown.new(Redcarpet::Render::HTML, autolink: true, tables: true).render(text)
end
end

Related

can someone explain this code in chef template

can someone explain this code in chef template? I would like to add an if condition to just variable2 . how do I approach this?
<%= #variable1 %>/*[!.][!g][!z] <%= #variable2 %>/*[!.][!g][!z] {
some random data in file
}
Ok, so in a Chef template (.erb file) anything outside the markers <%= ... %> and <% ... %> is plain text, i.e. it will be rendered as-is on the destination.
So /*[!.][!g][!z] inside the .erb file has no meaning. Once it is rendered on the destination, it may have relevance. And what it will do at the destination depends on what type of file it is, and what's going to use the file.
<%= #variable1 %> is to interpolate the value of variable1. Using <% ... %> will allow you to run Ruby script, i.e. if/else conditions, for loops etc.

Outputting method result to erb

I'm working on an application that creates random sentences. I have it working as a console application, and want to make a Sinatra app which lets me display the sentences on the browser.
I have a variable #grammar that is populated from a form. I want to pass this into a method a few methods which work together to take in a string and generate a random sentence from it using a lot of logic. My rsg.erb file looks like this.
Where 'The waves portend like big yellow flowers tonight.' is the output of the expand method. I would like to display this on the erb file so it is displayed on the browser.
How can I do that?
Can you try this:
<%= #grammar %>
<%-# Assigning values to the variables in first step %>
<%-
rds = read_grammar_defs(#grammar) #get text from file and parse
sds = rds.map { |rd| split_definition rd} #use split definition to make array of strings
tgh = to_grammar_hash(sds) #create hash
rs = expand(tgh) #create sentence
%>
<%-# Printing it in second step %>
<%= rs %>

I18n and Interpolation?

I want to be able interpolate variables inside of strings stored in a yml locales file. The only way I have figured out how to do this is with regex.
For example in en.yml I have
---
en:
byline: "By <strong>{{author}}</strong>"`
And then in my erb file I have:
<%= t(:byline).gsub!(/{{author}}/, current_page.data.author) %>
Is there an easier way to do this?
See Passing Variables to Translations in the Rails Internationalization API RailsGuide:
You can use variables in the translation messages and pass their values from the view.
# app/views/home/index.html.erb
<%=t 'greet_username', user: "Bill", message: "Goodbye" %>
# config/locales/en.yml
en:
greet_username: "%{message}, %{user}!"

How do I correct my script, that it doesn't matter what file name has the .xml that is uploaded?

My script edits an XML file using:
stringComplete = File.read("TheUpload.xml",encoding: "UTF-8").gsub(my mystery gsub)
and regenerates using:
newfile = File.open("EditXML.xml", "w")
newfile.puts "method(xyz)"
How do I correct my script so that it doesn't matter what file name has the ".xml" that is
uploaded and that every single user gets his own edited .xml file and not by someone else?
When uploading a file, you don't need to save it to disk on the server - simply read the upload IO (see here):
view.erb:
<%= form_tag({action: :upload}, multipart: true) do %>
<%= file_field_tag 'xml' %>
<% end %>
<%= form_for #upload do |f| %>
<%= f.file_field :xml %>
<% end %>
controller:
uploaded_io = params[:upload][:xml]
string_complete = uploaded_io.read.gsub(whatever)
For downloading, you also don't need to save to disk - simply serve the new file contents (see here)
send_data string_complete, filename: 'EditXML.xml'
If the files were uploaded to a directory in some other way, you can scan the input directory using Dir.glob, and then iterate over each, creating a new file in the output file with the name based on the input file's name:
Dir.glob(File.join(input_directory, '*.xml')).each do |input_file|
stringComplete = File.read(input_file,encoding: "UTF-8").gsub(my mystery gsub)
input_file_basename = File.basename(input_file)
newfile = File.open(File.join(output_directory, input_file_basename + '_output.xml', "w")
newfile.puts "method(xyz)"
end

Middleman variables visibility in config.rb and pages

I'm missing something about visibility of variables.
In my config.rb i'm using a data structure to generate dynamic pages:
#pages = [
{
id: "cookies",
title: "Happy Chocolate Chip Cookies",
quote: "These cute cookies are full of sweet chocolate and ready to give you energy!",
content: "Orecchini a monachella. Realizzati in fimo, dipinti a mano e rivestiti con vernice lucida."
},
....]
#pages.each do |p|
page "/creations/#{p[:id]}.html", :proxy => "item-template.html", :ignore => true do
#tile = p
end
end
The pages generation goes well, no problem with that. But..
How can i access this data structure also in order to provide dynamic links to the generated pages? I would like to be able to create an index page (let's call it creations.html) with the following code:
<ul>
<% #pages.each do |tile| %>
<li><a href="creations/<%= tile[:id]%>.html">
<%= tile[:title] %>
</a></li>
<% end %>
</ul>
No need to create a custom helper, you can use a yaml data file to populate your template and generate the list of links. Let me explain.
On the same level as source and build directories make sure you create a data directory.
ie:
build
source
data
Inside this create a file called "pages.yml" (for example).
This file needs to be specifically formatted so be careful (or use a yaml parser to make sure you don't have any errors - like a missing comma or escaped quote).
Using the data in your config.rb file, an example would be something like:
- id: "cookies"
title: "Happy Chocolate Chip Cookies"
quote: "These cute cookies are full of sweet chocolate and ready to give you energy!"
content: "Orecchini a monachella. Realizzati in fimo, dipinti a mano e rivestiti con vernice lucida."
- id: "bacon"
title: "Smoked bacon bits"
quote: "everything tastes better with bacon!"
content: "blah"
etc...
Now, in your config.rb file replace #pages.each do |p| with data.pages.each do |p|
data.pages.each loops through each item in the newly created yaml file
You can then simply reference the same file in your index file (creations.html) like so:
<ul>
<% data.pages.each do |tile| %>
<li><a href="creations/<%= tile[:id]%>.html">
<%= tile[:title] %>
</a></li>
<% end %>
</ul>
I had a similar problem around dynamic pages which you can refer to here
Hope this helps. Good luck!
Perhaps add a helper that returns the #pages data structure in your file creations.erb. I.e. in your config.rb file add:
helpers do
def dynamic_pages()
#pages
end
end
and then in your creations.erb have:
<ul>
<% dynamic_pages.each do |tile| %>
<li><a href="creations/<%= tile[:id]%>.html">
<%= tile[:title] %>
</a></li>
<% end %>
</ul>
And, if you want to reference dynamic pages in your dynamic pages(!), a helper could generate that html and you could call the ... nah, never mind!

Resources