<%= message.content %>
I can display a message like this, but in some situations I would like to display only the first 5 words of the string and then show an ellipsis (...)
In rails 4.2 you can use truncate_words.
'Once upon a time in a world far far away'.truncate_words(4)
=> "Once upon a time..."
you can use truncate to limit length of string
truncate("Once upon a time in a world far far away", :length => 17, :separator => ' ')
# => "Once upon a..."
with given space separator it won't cut your words.
If you want exactly 5 words you can do something like this
class String
def words_limit(limit)
string_arr = self.split(' ')
string_arr.count > limit ? "#{string_arr[0..(limit-1)].join(' ')}..." : self
end
end
text = "aa bb cc dd ee ff"
p text.words_limit(3)
# => aa bb cc...
Try the following:
'this is a line of some words'.split[0..3].join(' ')
=> "this is a line"
# Message helper
def content_excerpt(c)
return unlessc
c.split(" ")[0..4].join + "..."
end
# View
<%= message.content_excerpt %>
But the common way is truncate method
# Message helper
def content_excerpt(c)
return unless c
truncate(c, :length => 20)
end
Related
Please be patient with me, this is the first time that I have ever messed with Ruby. Basically here is my issue. I have a huge site that is just needing a single thing modified however I'm running into issues.
I am trying to get a PDF output for a lapel printer to wrap down to the next line. Here is my code.
def print_labels
quantity = params[:quantity].to_i
hashed_label = ActiveSupport::JSON.decode(params[:label])
p = InventoryItem.labels_pdf do |pdf|
(1..quantity).each do |i|
pdf.text("#{hashed_label['inventory_item_code']} #{hashed_label['label_description']} #{hashed_label['inventory_item_size']}", :style => :bold)
pdf.text("#{hashed_label['ingredients']}", :size => 9, :font => :serif)
#pdf.text(params[:label]);
pdf.start_new_page if i < quantity
end
end
send_data(p, :type => "application/x-pdf", :filename => "labels.pdf")
end
Here is the output in the PDF.
inventory_item_code label_description inventory_item_size
I am trying to get them to break between each item.
Is this using Prawn? You should be able to put newlines in all you want:
pdf.text("Here is some\ntext with\nnewlines")
So, a newline after the ingredients would just be:
pdf.text("#{hashed_label['ingredients']}\n", :size => 9, :font => :serif)
I want to split a string by whitespace
irb(main):001:0> input = "dog cat"
=> "dog cat"
irb(main):002:0> output = input.strip.split(/\s+/)
=> ["dog", "cat"]
This is good. However, I'm also doing this in the controller in Rails, and when I supply the same input, and have it print out the output #{output} into my view, it shows as dogcat instead of ["dog", "cat"]. I am really confused how that can happen. Any ideas?
I'm printing it using #notice = "#{output}" in the controller, and in my view I have <%= #notice %>
Rather than splitting your string in the controller and sending it as an array to your view, send the entire string to your view:
input = "dog cat"
#notice = input
Then, in your view, split your the string and display it as a stringified-array:
<%= array(#notice.strip.split(/\s+/)).to_s %>
If you print an array of strings, you'll get the strings all concatenated together. You'd get the same thing in irb if you had entered, print "#{output}". You need to decide how you want to format them and print them that way, perhaps with a simple helper function. For example, the helper could do:
output.each { |s| puts "<p>#{s}</p>" }
Or whatever you like.
Continuing with your example code:
>> input = "dog cat"
=> "dog cat"
>> output = input.strip.split /\s+/
=> ["dog", "cat"]
>> joined = output.join ' '
=> "dog cat"
Remember too that Ruby has several helpers like %w and %W for letting you convert a string into an array of words. If you're starting with an array of words, each of which may have whitespace before and after its individual item, you might try something like this:
>> # `input` is an array of words that was populated Somewhere Else
>> # `input` has the initial value [" dog ", "cat\n", "\r tribble\t"]
>> output = input.join.split /\s+/
=> ["dog", "cat", "tribble"]
>> joined = output.join ' '
=> "dog cat tribble"
Calling String#join without any parameter will join stringish array items together with no separation between them, and is what seems to be done in your example where you just render the array as a string
>> #notice = output
>> # #notice will render as 'dogcat'
As opposed to:
>> #notice = input.join.split(/\s+/).join ' '
>> # #notice will render as 'dog cat'
And there you go.
I'd like to debug a variable #num in my Rails controller, so I'm evaluating
<%= #num %>
in my Rails view. However, I cannot distinguish between #num being '', ' ', and ' ' (and other different types of whitespace) when it's printed in the HTML. Is there any way to print it out clearly?
If you want to be really sure:
<%= #num.inspect %>
When #num = ' ' this should render:
" "
#inspect is great when you want to a representation of some object as a string.
If this is a complex object or large array or deep hash, I often prefer #to_yaml for inspection which lays it out in a somewhat readable format.
# controller
#foo = {:a => [:bar, :baz], :b => 123, :c => 'omg'}
# view
<pre><%= #foo.to_yaml %></pre>
# visible output
---
:b: 123
:c: omg
:a:
- :bar
- :baz
<%=debug #num %>
Will format it in haml.
<%= #num.inspect %>
Will format it as "p" does.
See Debugging Rails Applications (rails guides)
I want to highlight found words in text, for example, as shown here.
As far as I know I must follow these steps:
1) In my model, I must add :stored => true option to the field which I want to highlight:
searchable do
text :title, :stored => true
text :description
end
2) In my controller, I have to declare which field I want highlighted:
def search
#search = Article.search do
keywords params[:search] do
highlight :title
end
end
end
3) In the view I'm not sure what to do, I tried this:
- #search.each_hit_with_result do |hit, result|
%p= link_to raw(hit_title(hit)), article_path(result)
It is what doing method hit_title:
def hit_title(hit)
if highlight = hit.highlight(:title)
highlight.format { |word| "<font color='green'>#{word}</font>" }
else
h(hit.result.title)
end
end
But it doesn't work as expected, it always highlights the first word of the title, even if the searched word is at the end of it.
Is there an easier way to do this?
I bumped into this looking for a solution to render highlights from sunspot search on rails view.
I didn't find much of a ready solution anywhere, so I used part of this post to make one of my one.
I am quite new to rails so this might not be fully the RoR way.
In my case, I did a full text search on two fields, call them notes and description.
In order to be able to render to html the highlights, I introduced a hash of values containing the id of the record, the name of the column and its highlighted value, adequately formatted. This allows me to highlight the search results on different fields.
entry.rb:
searchable do
text :description, :stored => true
text :notes, :stored => true
end
entries_controller.rb:
#search = Entry.search
if params[:search].nil? || params[:search].empty?
stext=''
else
stext=params[:search]
end
fulltext stext, :highlight => true
paginate(page: params[:page], :per_page => 10)
end
#entries=#search.results
#results=Hash.new
#search.hits.each do |hit|
hit.highlights(:description).each do |highlight|
id=hit.primary_key.to_s.to_sym
fr=highlight.format { |word| "<result>#{word}</result>" }
#results.merge!(id => ["description",fr])
end
hit.highlights(:notes).each do |highlight|
id=hit.primary_key.to_s.to_sym
fr=highlight.format { |word| "<result>#{word}</result>" }
#results.merge!(id => ["notes",fr])
end
end
and on the view, wherever I want to render any value of those, I do the following:
<% #entries.each do |f| %>
<% j=f[:id].to_s.to_sym %>
<% if !#results[j].nil? && #results[j][0]=="description" %>
<%= #results[j][1].html_safe %>
<% else %>
<%= f[:description] %>
<% end %>
[...] (likewise for notes)
<% end %>
Please, note I created a css definition for <result> markup to make the text notable.
Code looks good to me for highlighting the first matching word in the title, since I have similar code. Have you tried rebuilding your solr index and restarting the servers?
Also, can you try reverting your solrconfig.xml to its default values? Someone had a similar problem after modifying solrconfig.xml, Ref https://groups.google.com/forum/#!searchin/ruby-sunspot/highlight/ruby-sunspot/kHq0Dw35UWs/ANIUwERArTQJ
If you want to override the highlighting option in solrconfig.xml, search for max_snippets on this site http://outoftime.github.io/ . You may want to try options like
highlight :title, :max_snippets => 3, :fragment_size => 0 # 0 is infinite
Are you using substring search? I've got the same problem here and realized that enabling substring match by following sunspot wiki tutorial led to the problem.
I'm quite long description that I want to truncate using truncate helper.
So i'm using the:
truncate article.description, :length => 200, :omission => ' ...'
The problem is that I want to use more as a clickable link so in theory I could use this:
truncate article.description, :length => 200, :omission => "... #{link_to('[more]', articles_path(article)}"
Omission text is handled as unsafe so it's escaped. I tried to make it html_safe but it didn't work, instead of link [more] my browser is still showing the html for that link.
Is there any way to force truncate to print omission link instead of omission text?
I would suggest doing this on your own in a helper method, that way you'll have a little more control over the output as well:
def article_description article
output = h truncate(article.description, length: 200, omission: '...')
output += link_to('[more]', article_path(article)) if article.description.size > 200
output.html_safe
end
With Rails 4, you can/should pass in a block for the link:
truncate("Once upon a time in a world far far away",
length: 10,
separator: ' ',
omission: '... ') {
link_to "Read more", "#"
}
Dirty solution... use the method "raw" to unescape it.
you have to be sure of "sanity" of your content.
raw(truncate article.description, :length => 200, :omission => "... #{link_to('[more]', articles_path(article)}")
raw is a helper acting like html_safe .
bye
edit: is not the omission of being escaped , but the result of truncate method.
I encountered a similar situation and this did the trick. Try (line breaks for readability):
(truncate h(article.description),
:length => 200,
:omission => "... #{link_to('[more]',articles_path(article)}")
.html_safe
You can use h to ensure sanity of article description, and since you are setting the link_to to a path you know to not be something potentially nefarious, you can mark the resulting string as html_safe without concern.
TextHelper#truncate has a block form of truncate, which lets you use a link_to that isn't escaped, while still escaping the truncated text:
truncate("<script>alert('hello world')</script>") { link_to "Read More", "#" }
#=> <script>alert('hello world'...Read More
The only one that worked for me :
<%= truncate(#article.content, length: 200, omission: " ... %s") % link_to('read more', article_path(#article)) %>
I had the same problem, in my case i just used :escape => false.
That worked:
truncate article.description, :length => 200, :omission => "... #{link_to('[more]', articles_path(article)}", :escape => false
From documentation :
The result is marked as HTML-safe, but it is escaped by default, unless :escape is false....
link: http://apidock.com/rails/ActionView/Helpers/TextHelper/truncate