I have a markdown text saved in the databse and I want to show it as html to the user. I am using markdown.js as the processor and I pass the big multiline html string from rails to javascript by rendering a js.erb file from the controller.
But since it is multiline, the javascript becomes invalid. Is there any rails function which will take the whole string and assign it as a single line string to javascript variable. I cannot use html_safe also as some things might be escaped. What is the best way to handle markdown?
sample markdown
![enter image description here](https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRiOb7-0qeyx73XuXNqzLpxgXTlf5UMrMnF5zm-UKn3wLaXCW0UUw "enter image title here")
Hello
If you render erb server-side anyway, you will probably be better rendering Markdown server-side as well. You can use Redcarpet for that.
Add gem redcarpet to your Gemfile.
Run bundle install
Use it:
text = "my _markdown_ *variable*"
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
markdown.render(text)
It will be a good idea to save rendered HTML in the database, to save CPU time on re-rendering the same text every time you want to show it to client. So you can add something like this to your model:
class Article
# let's say that model has 'source' attributes with Markdown
# and we want to put resulting HTML into 'html' attribute
before_save :markdown
def markdown
self.html = Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(source)
end
end
Related
I'm having trouble getting Slim to render my markdown:
div.container
div.row
div.col-md-8.job_description
markdown:
= #listing.job_description
That just renders the string
This is an h1 ## h2 ### h3 > this is a quote * hello * goodbye foo
No line breaks or anything (which are contained in the actual string)
How do I get this to render properly? Thanks!
I gave up on using markdown: in slim, had tried everything.
I ended up creating this helper, place it in just any file in app/helpers
def markdown(content)
return '' if content.blank?
markdown = Redcarpet::Markdown.new(Redcarpet::Render::XHTML, autolink: true, space_after_headers: true)
sanitize(markdown.render(content)).html_safe
end
And then in a view
= markdown #listing.job_description
You will of course have to install the redcarpet gem.
gem 'redcarpet'
Rendering Markdown out of a variable in this way isn't possible, as Slim first renders the Markdown (or any other embedded engine language) and only after that interpolates the variable contents.
It makes sense that it would work this way as Slim's embedded engine tags are intended as a way of including different languages in-line so you can read them there. If the markdown isn't included in literal form in the template, there's no advantage to using the embedded engine over simply rendering the Markdown before you pass it to Slim (as HTML, and using '==' to prevent further processing by Slim).
I think, also, that it's set up like this because it's intended to provide and easy way for interpolating text into Markdown - which doesn't itself have a means of interpolation - within the same template as everything else.
The helper Iceman suggests is a nice way to do it. I'd probably call it outside of the template, but that's just because it's my personal preference to do as little as possible inside the template.
Looks like your markdown content is not indented under markdown:, so it won't be processed by markdown.
It should look more like this:
div.col-md-8.job_description
markdown:
= #listing.job_description
See this section of the docs for more information.
Essentially I'm trying to implement a way so that users can edit slim that is stored in the database.
For example they would use the form to create a new page and insert the html for that page in a text field which would be saved in the database. I want to allow them to edit that page in slim. By the way the html stored is slim not plain html.
If I store slim in the database how do I get rails to render the html properly on the client side in production? So in other words would rails automatically do this since the view is being render like so:
views/page/view.html.slim
page.header
page.content
page.footer
or would I have to figure out a way to convert on the fly? I might be making this more complicated then I should but I'm new to this
If I understand you correctly you want to convert the slim to Html and output that in your views.
This is directly from slims doc. This is how it processes slim files and outputs it.
Tilt.new['template.slim'].render(scope)
Slim::Template.new('template.slim', optional_option_hash).render(scope)
Slim::Template.new(optional_option_hash) { source }.render(scope)
so in short
Slim::Template.new(page/view.html.slim).render
put that in a module to make it prettier and I think you're good. You may want to use rails path helper to get the direct link for the view. You may also want to consider figuring out a way to catch the errors in indentation so that your output doesn't bug out in production. Some kind of validation that prevents it from saving if not properly formatted should help.
I want the users on my blogsite to be able to type in markdown text in a textarea to make a blogpost. This markdown text would then be converted with a tool like Redcarpet or kramdown. Now I also want the user to be able to call a partial view that lays out some pictures. So in other words, I want the user to be able to type in the following code anywhere in between his markdown text (and it being interpreted as erb code)
<%= render partial: "slider", locals: {imgs: ["image1.jpg", "image2.jpg"]} %>
Is this possible somehow? kramdown allows you to use block-level HTML tags (div, p, pre, …), so maybe this could be used to some advantage?
Do you really want your customers to be able to write ERB? That's extremely dangerous, they can use any Ruby function in ERB, including Kernel functionalities. What about allowing a simple templating system, either a custom one or an existing one. For example you can use Liquid (from Shopify), provide some custom tags so they won't need all the boilerplate but just something like {% dosomething 'partial', 'img1', 'img2' %}, then you first convert liquid into normal text, then you convert markdown to html, cache it and display that to the user. An example:
# get your customer text from somewhere, like params[:markdown_text]
template = params[:markdown_text]
markdown = Liquid::Template.parse(template).render
html_text = Redcarpet::Markdown.new(renderer, extensions = {}).render(markdown)
puts html_text.to_s # => text with html tags, ensure to use `html_safe` on it in views
And you have your text ready
I have a page where I use RedCloth to use markdown for the text and images. I want to be able to place a form somewhere in the text by putting the string [Form] and my application does a substitution to replace [Form] with the ruby code to execute a Rails form.
How do I do this? I currently executve the RedCloth-ed text with a "<%=h %>" so I don't know how to substitute a string with the Rails form code?
Thanks!
For example, in my view, I currently display a mp3 player using a gem and its helper:
5 #landing_page
6 #message
7 = mp3_player #landing_page.mp3.url unless #landing_page.mp3_file_name.blank?
8 = #redcloth_landing_page
But I actually want more flexibility in terms of being able to place this mp3 player somewhere within the redcloth document by using a substitution string {mp3}.
I'd like where the {mp3} is placed to be where the mp3 player shows up.
First of all I think i understood your question correctly :D,
If you want to add a form (with html tags) as string and wish to function it as a normal form you should look in to template language like 'liquid' (https://github.com/tobi/liquid/). and it works with 'RedCloth' too
cheers
sameera
I'm looking for advice on how to clean submitted html in a web app so it can be redisplayed in future with out styles or unclosed tags wrecking the layout of an app.
On my app rich HTML is submitted by users with YUI Rich text editor, which by default runs a few regexps to clean the input, and I'm also calling the [filter_MSWord][1] to catch any crap sent in from office
On the back end, I'm running ruby-tidy to to sanitize the html before being displayed as comments, but on occasion badly pasted html still affect the layout of the app I'm using - how can I safeguard against this?
FWIW here are the sanitizer settings I'm using -
module HTMLSanitizer
def tidy_html(input)
cleaned_html = Tidy.open(:show_warnings=>false) do |tidy|
# don’t output body and html tags
tidy.options.show_body_only = true
# output xhtml
tidy.options.output_html = true
# don’t write newlines all over the place
tidy.options.wrap = 0
# use utf8 to play nice with rails
tidy.options.char_encoding = 'utf8'
xml = tidy.clean(input)
xml
end
end
end
What else are my options here?
I personally use the sanitize gem.
require 'sanitize'
op = Sanitize.clean("<html><body>wow!</body></hhhh>") # Notice the incorrect HTML. It still outputs "wow!"
I use the sanitize helper available from ActionView
Module ActionView::Helpers::SanitizeHelper