I have a text_area in my rails app where users can paste plain text or code. I really don't want to ask the user to choose text or code for me but want to make it like a WYSWYG text area
Right now I use pre tag. This renders code comments ok but makes text comments look visually ugly.
I can use a syntax highlighting gem, but this requires me to know that the pasted text is code.
Q: Is there any inbuilt apis in rails/ruby to validate if the value in a text area is code or text?
<% if !comment.content.blank? %>
<p> <pre> <%= simple_format comment.content %></pre> </p>
<% end %>
You can instruct the user to wrap the code section around a specific keyword..for instance {code}
then in your template you can extract and decorate the the code section:
<p> <pre><%= comment.content.scan(/{code}(.*?){code}/m) %></pre></p>
Related
I have a text_area tag which allows the user to enter his Bio. When a user is tyoing and if he hits enter or return, a new line starts. But when he saves his input all the text is displayed in one paragraph. I want functionality similar to what stack overflow has.
For example - I hit enter now
This text appears on a new line*
How can I do this?
This is my code in Rails:
<%= form_for :profile do |profile| %>
<%= profile.text_area :bio %>
<%= f.submit "Save Bio" %></p>
<% end %>
You should use text editor for example ckeditor (to simplify web content creation), and in view try simpleformat or raw:
<%= simple_format("Here is some basic text...\n...with a line break.") %>
<%= raw("Here is some basic text...<br/>...with a line break.") %>
There are many ways to handle this. When displaying text previously inputed in text area you can:
replace newline characters with <br/> tags
use <pre> tag and display text inside that tag
split text by newline characters and then wrap each of the chunks into <p> tags
When using approach 1 or 3, make sure to pass text through raw helper, so that any tags within text are displayed. Be aware though, that user may pass arbitrary html inside the textarea, hence your code may be subject to xss attacks.
I am working on a style guide which displays the code, as well as the output. It is currently structured so that the code only needs to be described once, and is displayed in both its raw and interpreted versions, like so:
<% code = <<PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
<div>
#{ image_tag 'image.png' }
</div>
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%>
<%= raw code %>
<%= content_tag :pre, code, class: "prettyprint linenums" %>
This is great, and fairly easy to maintain. The problem comes in with the rails helpers, like image_tag in the above example. The view example correctly displays an image in a div, and the code example displays the relevant HTML. In this case, the relevant HTML includes an anchor tag - the results of the image_tag method, not the call itself.
I would prefer the code examples to display the helper methods, rather that their results. I am able to make this work by specifying the example code in a file, and either rendering or reading the file. I would prefer to make this work by specifying the code in a variable, as above, but I can't seem to get an ERB delimiter to work inside of a string inside of an erb block. Even the simplest case of <% foo = '<%= bar %>' %> doesn't work at all. I've tried playing with the syntax (<%% %%> and % % for example), using details from the official documentation, without much success.
The only information I could find on the matter is here, using <%= "<" + "%=" %> link_to <%= image.css_tag.humanize %> <%= "%" + ">" %> %>, which does not work in this use case (if at all).
So, is there a way to specify a string that contains a ERB end-delimiter (%>) in an ERB string, or am I stuck using the slightly clunkier file-read method? Thanks!
Edit:
What I would like to end up with is a working version of this:
<%# Idealized code - does not work %>
<% code = <<PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
<div>
<% image_tag 'image.png' %>
</div>
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%>
So that <%= raw code %> would (continue to) output:
<div>
<img src="/images/image.png" alt="Image" />
</div>
And <%= content_tag :pre, code, class: "prettyprint linenums" %> would output:
<pre class="prettyprint linenums">
<div>
<% image_tag 'image.png' %>
</div>
</pre>
Instead of what it currently does when using a variable, which is:
<pre class="prettyprint linenums">
<div>
<img src="/images/image.png" alt="Image" />
</div>
</pre>
I want users to be able to copy the code example and paste it into a new view, without having to translate HTML back into the helpers that produce them. I think what I basically need is an alternative ERB delimiter, in the same way that ' and " (or even %q{}) vary for strings. It seems that even though the final ERB delimiter is occurring inside of a string, it is being actually processed as the end of the block. The simplest case of <% foo = '<%= bar %>' %> demonstrates somewhat what I want to accomplish. In a generator, you might use <% foo = '<%%= bar %>' %> (or something similar), to tell it not to process as ERB right then and there. This all works fine when reading from a file, or even in a pure rb file (like a helper), but it makes the most sense to put it in the view, in this case, as it is intended to be easily manipulated by our designers.
If I'm understanding you right, your real problem is that heredocs behave like double quotes as far as interpolation is concerned. So all you need is a quoting mechanism that behaves like single quotes. Ruby has lots of string quoting mechanisms, in particular we have %q{...}:
<% code = %q{
<div>
#{ image_tag 'image.png' }
</div>
} %>
You can use other delimiters if you'd like: %q|...|, %q(...), etc. There's still a change of course but at least you don't have to worry about interpolation problems.
If you really want to use a heredoc, you can specify the heredoc terminator with quotes and the corresponding quoting style will apply to the content:
<% code = <<'PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR'
<div>
#{ image_tag 'image.png' }
</div>
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%>
The single quotes in <<'PLACE...' specify that single quoting rules (i.e. no interpolation) apply to the heredoc's content.
Of course none of that stuff will work with embedded ERB like this:
<% code = %q{
<div>
<% ... %>
</div>
} %>
because the ERB parser will see the first %> as the closing delimiter for the outer <% code... part. Fear not, I think I have a plan that will work without involving gross hacks or too much work.
Some preliminaries:
Rails uses Erubis for ERB processing.
Erubis allows you to change the delimiters with the :pattern option to its constructor.
Rails uses Tilt and Sprockets to handle the template processing pipeline, these allow you to make the right things happen to pancakes.js.coffee.erb in the right order.
Using the above you can add your own template format that is ERB with a different delimiter and you can have Rails use this new format to handle your "special" sections before the normal ERB processing can make a mess of things.
First you need to hook up Tilt. If you have a look at lib/tilt/erb.rb in your Tilt installation, you'll see the Erubis stuff in Tilt::ErubisTemplate at the bottom. You should be able to subclass Tilt::ErubisTemplate and provide a prepare override that adds, say, a :pattern => '<!--% %-->' option and punts to the superclass. Then register this with Tilt and Sprockets in a Rails initializer with something like this:
Tilt.register(Your::Template::Subclass, 'klerb') # "kl" for "kludge" :)
Rails.application.assets.register_engine('.klerb', Your::Template::Subclass)
Now your application should be able to handle .klerb files with <!--% ... %--> as the template delimiters. And you can also chain your klerb with erb using names like pancakes.html.erb.klerb and the file will go through klerb before the ERB; this means that templates like this (in a file called whatever.html.erb.klerb):
<!--% code = <<PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
<div>
<% image_tag 'image.png' %>
</div>
PLACE_THE_EXAMPLE_CODE_BETWEEN_THESE_TWO_LINES_EXACTLY_AS_YOU_WANT_IT_TO_APPEAR
%-->
<!--%= "code = escape_the_erb_as_needed(%q{#{code}})" %-->
<% do_normal_erb_stuff %>
will do The Right Thing.
You'd need a helper to implement the escape_the_erb_as_needed functionality of course; a little experimentation should help you sort out what needs to be escape and in what way.
All that might look a bit complicated but it is really pretty straight forward. I've added custom template processing steps using Tilt and Sprockets and it turned out to be pretty simple in the end; figuring out which simple things to do took some work but I've already done that work for you:
Tilt::Template subclass, you get this by piggy backing on Tilt::ErubisTemplate.
Register with Tilt by calling Tilt.register.
Register with Sprockets by calling Rails.application.assets.register_engine.
...
Profit.
i replaced line feed characters with HTML line break as
#post.description.gsub(/\n/, "<br/>")
I am trying to show the output within tags. But I see as follows:
Used, like new book<br/>New book costs $150<br/>Awesome book!
Need help. Thanks.
Use simple_format for this as it will automatically convert new lines into breaks.
<%= simple_format(#post.description) %>
I store the linebreaks as "line\n\nline" in the database.
When i am displaying it, I convert it using this method:
def showLineBreaks(from_textarea)
from_textarea.gsub(/\n/,"<br/>")
end
But these renders the text as
line<br><br>line
instead of showing the linebreaks.
What is the right way to do this?
You probably need to flag your content as html_safe for it to display properly, otherwise the view will render it as the string should be displayed.
<%= showLineBreaks.html_safe %>
If you're trying to display newlines saved from text areas, you could do the following in your view:
<%= simple_format from_textarea %>
No need to do manual substitution in this case.
I need to display user comments, omitting HTML to prevent attacks (when custom styled elements can be posted as comments)
The only thing, i would like to keep by displaying - is tag
I displaying the comment in this way:
<p class="content"><%=h comment.content.gsub(/\n/,"<br/>") %></p>
Comment is suppossed to be saved in database without any markup
Line ending are converted to "br" tags
But, sure, they are gone, because of =h output mode.
Is there a way to kill all html, except "br" tags ?
You could either use sanitize which keeps only specified HTML tags:
<%= sanitize comment.content.gsub(/\n/,"<br/>"), :tags => ['br'] %>
or (in your case preferably) change the order of both and do the html_escape yourself:
<%= html_escape(comment.content).gsub(/\n/,"<br/>") %>
I'd recommend to use white_list plugin. It's safety for XSS attacts and you will be able to control list of allowed tags