How do i style a JSON feed in my view? - ruby-on-rails

My rails app gets the following JSON feed from mixcloud and sticks the results into my index page
At the moment when I do this, the entire contents of my feed are displayed unformatted in one big blob of scary looking text (without the curly JSON brackets)
I only want to display specific values from the feed in the view.
From the feed in question lets say for simplicity that I just wanted to display all values with a key of "url"
In case I'm doing something wrong here's my code:
# podcast controller
def index
# I'm using a class method to get the feed
#feed = Podcast.feed
end
# podcast model
def self.feed
feed = JSON.parse(open("http://api.mixcloud.com/alivefrommaryhill/feed").read)
end
# index.html.haml
.feed
= #feed
I can't figure out how to style the results and display only certain items from the feed. Is my approach wrong?

I've done something similar using HTTParty and Hashie gems.
This example loops through the first 10 results:
#controller
def index
#result = Hashie::Mash.new HTTParty.get("http://api.mixcloud.com/alivefrommaryhill/feed")
end
#index.html
<% #result.data[0..10].each do |e| %>
<%= e.url %>
<br/>
<% end %>
If you wanted the 'small pictures' you would do
<% #result.data[0..10].each do |e| %>
<%= e.from.pictures.small %>
<br/>
<% end %>
Hope this helps :-)

Instead of writing the json directly to your view, maybe you could write a clientside javascript function that converts the json into html markup. For, example, maybe use jquery like described here? Best way to display data via JSON using jQuery
Or, similarly, you could still write the json directly in your view, but write it out as the value to a javascript variable instead of writing it as html. Then you could write a javascript function that reads and parses the javascript variable after the page loads, converts it to html, and inserts into the DOM. This method would be similar to the answer in the link above, except you wouldn't have to make a ajax request, you can simply process the data since it will already be available locally in a js var.

Related

Rendering attribute with two different formats

I have an object that has an attribute using a markdown language for the past few years and recently the attribute is now switched to using html. How do I render all the past campaign descriptions with the markup language and how do I render all the new campaign descriptions with .html_safe
Html_safe
<h6 class="text-muted" itemprop="description">
<%= #campaign.product_description.html_safe %>
</h6>
Markdown
<h6 class="text-muted" itemprop="description">
<%= Campaign::Format #campaign.product_description, {render_html: true} %>
</h6>
How can I render both? That way For all the old campaigns it renders the markup and for the new campaigns it renders the html. When I include html_safe and the markdown on the same line it only does the markup and not the html from a WYSIWYG editor.
Several options:
Add a flag to your campaigns. Something like uses_html_description. Set its values correspondingly. And switch on that in the view.
Do a data migration and replace all descriptions in old format with the new html format.
Between these two, I'd go with the latter.
My first thought is that I would backfill your DB converting all the old records to the new format.
Otherwise, make a view helper method in app/helpers/application_helper.rb something like:
def description_text campaign
if campaign.created_at > Time.new(2019,3,1).in_time_zone
campaign.product_description.html_safe
else
Campaign::Format campaign.product_description, {render_html: true}
end
end
Note that you can probably also actually detect the HTML in the string if you'd prefer that to the time-based thing, like:
def description_text text
if text.starts_with? "<html" # or whatever
# ...

How it's possible to send an array from one view to the next

I have a Controller with the function getAccounts where I look for certain accounts. My idea is to first show the number of results and then send the result array to the next function called showAccounts which generates the view. First of all I declared the result array as an instance variable. Then I tried to send with a form tag. It does not work ... Has anyone an idea?
def getAccounts
filter = '(uid='+params[:id]+')'
attrs = ['*']
#accounts=Array.new
conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn=admin, dc=cippool-mb, dc=rwth-aachen, dc=de','DLPins!')
conn.perror("bind")
begin
conn.search($base, $scope, filter, attrs) { |entry|
setAttributes(entry)
}
rescue LDAP::ResultError
conn.perror("search")
exit
end
conn.perror("search")
conn.unbind
end
def showAccounts
end
The view where I send the data.
Es wurden <%= #accounts.size %> Accounts gefunden.
<%= form_tag :action => "showAccounts" do %>
<%= hidden_field_tag "accounts", #accounts %>
<%= submit_tag "Anzeigen" %>
<% end %>
I can also paste the view where I need this array, but I dont't think it's relevant for this question. I use Rails 3.2.7 and Ruby 1.9.2p0
If you want to pass some large amount of data between separate requests I would suggest using session, it's designed for such things.
If you debug(#accounts) you'll see what it passes -- something like <#0x7187237 Array> which is not what you want!
If you really want to pass in the accounts array, you'll need to serialize it to a text format to put in a hidden field. That's going to probably be a HUGE chunk of data though if #accounts is large.
That said, you could dump it to YAML or JSON, or use one of the serialization functions in Ruby or put it into a custom text format of your own (not recommended). Keep in mind then that you need to deserialize on the next page before you use it.
I'm assuming part of the wanting to pass it to the next step is to avoid an expensive LDAP request. You might want to look at putting in a lightweight cache -- redis for example -- to temporarily store the requests.

Rails 3 / Controller / Flash hash

I want to be able to pass multiple messages to the flash hash, inside of my controller, and have them display nicely together, e.g., in a bulleted list. The way I've devised to do this is to create a helper function in my Application Controller, which formats an array into a bulleted list, which I then pass to, in my case, flash[:success]. This is clearly not the Rails Way because, i.a., my bulleted list gets encoded. That is, instead of getting:
Message 1
Message 2
I get:
<ul><li>Message 1</li><li>Message 2</li></ul>
I'm sure I could figure out a way to raw() the output, but isn't there a simple way to get something like this working? Perhaps there's an option to pass to flash[]? Something else?
I used render_to_string and a partial instead of a helper to achieve something similar.
# app/controller/dogs_controller.rb
def create
#dog = Dog.new(params[:dog])
#messages=[]
if #dog.save
#messages << "one"
#messages << "two"
flash[:notice] = render_to_string( :partial => "bulleted_flash")
redirect_to(dogs_path)
else
render :action => 'new
end
end
Then I format the array of flash messages in an HTML list
# app/views/dogs/_bulleted_flash.html.erb
<ol>
<% #messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ol>
Which produces the following HTML
# http://0.0.0.0:3000/dogs
<body>
<div id="flash_notice">
<ul>
<li>one</li>
<li>two</li>
</ul>
</div>
...
</body>
If you need to continue using a helper then I think you need to append the html_safe method to your string to prevent it from being encoded (which rails 3 does by default). Here is a question showing how to use html_safe in a similar fashion
If you are using Rails3, try the raw method.
raw(my_html_string)
And it won't escape the html. Oh, sorry, I just read your last sentence. Check out this information, "Rails 3 flash message problems", it looks like it may be what you are looking for:
http://www.ruby-forum.com/topic/215108
Usually I would ask for more information about your views and layouts in this situation, because scaffolding doesn't display flash[:success] by default.
The way I solve this is to totally redo my flash messages usually, by making the flash[:whatever] an array every time, and in my layout handling that array instead of just the notice. Remember that flash is just a Hash, you're just setting values.
However if you just want to do this with the setup you have now (helper putting the HTML inside the flash[:success]), you can change the way that the flash messages are displayed in your layout file. By default they are just use <%= flash[:success] %>, which automatically escapes HTML. To make it not do that for the flash messages, change it to <%=raw flash[:success] %>

rails3 + liquid parse question

I have a question in using luquid. My question is like this,
I have a model called 'Page' (with is an ActiveRecord::Base
inherited) , and it has a column called 'content' which will store
the html page content.
I have a code to display it as follows
<%#template = Liquid::Template.parse(page_content) %>
<%= #template.render('page_content' => yield) %>
where 'page_content' has implemented in application helper as follows
def current_site_layout
Page.find(1). content
end
but my problem is if I have content as follows
<h1>This is a test</h1>
It will display in the page as
<h1>This is a test</h1> (with <h1></ h1> tags)
where as I want it to print like This is a test (formatting
applied as h1)
what am I missing here , and I think I will have to use liquid_methods
or something like that. But since I'm new to liquid I'm not sure which
method to use.. can someone help me
I'm on rails3 and using gem 'liquid 2.2.2', from 'github.com/GnomesLab/
liquid.git'
thanks in advance
cheers
sameera
In rails 3, strings are escaped by default. To display unescaped strings, you need to call raw method explicitly.
<%#template = Liquid::Template.parse(page_content) %>
<%= raw #template.render('page_content' => yield) %>

Rendering a variable with erb

I've got the following problem: I have rhtml (html minced together with ruby inside <% %> and <%= %> tags) stored in a database which I want to render. The information is acquired through a query. I need to be able to evaluate the information I get from the database as though as it was normal content inside the .erb-file. What I currently have:
<% #mymods.each do |mod| %>
<%= render_text(mod["html"])%>
<% end %>
Where mod["html"] is the variable containing the rhtml-code and #mymods an array of objects from the query. I have currently no idea what function I should use (render_text does, of course, not work).
Help is greatly appreciated.
/TZer0
You can use the ERB object to render text without the text being in a file.
Just pass the text with the <%= %> tags. You could put something like the following as an application_helper function.
def render_erb_text(text, args={})
b = binding
template = ERB.new(text, 0, "%<>")
template.result(b)
end
And then in your template
<%= render_erb_text("<%= %w(hi how are you).join(' - ') %>")%>
You might also consider rendering the text in your controller as you can handle any render errors better there than during view evaluation.
Take a look at the ERB documentation for more information regarding variable binding etc.
I'm not familiar with the details of how this works under the covers, but there could be some serious risk in running this code on bad or malicious database data. Evaluating ruby code from user input or any un-vetted source should be done very carefully, if at all.

Resources