3

So here is my point, i tried to follow some tutorial and read all of the references in the end from http://8raystech.com/2011/11/28/how-to-create-embeddable-widgets-with-rails

I spent almost 2 days searching for the little mistake I obviously made somewhere since I'm new to ruby on rails. I think it might be a route error since when I inspect elements via Chrome, i see the following error: EDIT:

"GET http://localhost:3000/widget 500 (Internal Server Error)"

I tried many things on it desperately but here is my current code:

My widget controller looks like this: (widget_controller.rb)

class WidgetController < ApplicationController
    def show
        @content = render_to_string(:partial => 'widget/embed', :layout => false)
    end
end

My view using javascript (show.erb.html)

(function() {
    document.write(<%= @content.to_json %>)
})()

The partial is not really important i think but here is an example: (_embed.erb.html)

<style>...</style>
<div class="widget-communication">
    <div>Bla bla bla</div>
    ...
</div>

and for the last, in the routes.rb

...
match 'widget', to: 'widget#show'
...

So I tested in local to load my widget using this:

<script src="http://localhost:3000/widget" type="text/javascript"></script>
kulssaka
  • 226
  • 8
  • 27
  • What does happen if you try to open http://localhost:3000/widget via browser? – Gabber Oct 15 '12 at 15:14
  • it puts: `Template is missing Missing template widget/show, application/show with {:locale=>[:fr], :formats=>[:html], :handlers=>[:erb, :builder, :coffee, :haml]}. Searched in: * "/Users/....../rails/application/app/views" * "/Users/....../.rvm/gems/ruby-1.9.3-p194@rails3/gems/devise_invitable-1.1.0/app/views" * "/Users/....../.rvm/gems/ruby-1.9.3-p194@rails3/gems/devise-2.1.2/app/views"` – kulssaka Oct 15 '12 at 15:25
  • http://stackoverflow.com/questions/6495046/template-is-missing – Gabber Oct 15 '12 at 15:30
  • i'll have a watch on that and keep you in touch, thanks – kulssaka Oct 15 '12 at 15:35
  • I don't think the problem was there since i'm not redirecting to anything, and I don't have a create method. Same result missing template, but the problem should be elsewhere :'( – kulssaka Oct 15 '12 at 15:43

3 Answers3

3

I dont't know the widget but it seems You still want to render partial as HTML not as a JS. You are just assigning a string to value content and it wants to use default render action. Try to use not .erb but .js file extension (show.js.erb), so:

in the controller you still need to return a collection, ie:

class WidgetController < ApplicationController
  respond_to :js, only: :show

  def show
    @user = User.find params[:id]
  end
end

and in the view (show.js.html):

document.write("<%= escape_javascript(render(:partial => 'widget/embed', :locals => {:user => @user})).html_safe) %>");

Though I don't recommend using respond_to :js. It's very hard to debug, it's pretty slow and it mixes html and js logic.

Eru
  • 675
  • 4
  • 8
  • his seems interesting, however I don't understand why the controller needs to return a collection. Well, I tried with you example, but i got: the same missing template error (I added the following lines to my routes.rb as well: **match 'widget/:id', to: 'widget#show' , id: '.*/ ** and this **resources :widget do member do get :user end end ** ) So I'm not sure about using user, and I don't know what i could return instead since the widget don't interact with collections like Users and Companies etc... – kulssaka Oct 15 '12 at 16:52
  • As you can see `@user` is an object, not a collection. I wrote it there only for example purpose. You may as well have action defined as `def show;` so it will only render a view. You might also name your controller `WidgetsController` and create routes like: `resource :widgets, only: :show` instead of `match` – Eru Oct 16 '12 at 17:03
  • hmm I see :) I'll keep that in mind :) i voted +1 for your answer even if i answered myself. Have a nice day – kulssaka Oct 17 '12 at 15:01
2

Ok so here is another way to do it... JQuery and Json....

So use directly used a controller like your user controller or whatever information you want to put in your widget, in my example, some information on companies.

so add a method widget in your controller like:

def widget
    @company = Company.find(params[:id])
    @logo_url = @company.logo_url(:mini)
    respond_to do |format|
      format.json { render :json => {:company => @company, :url => @logo_url}, :callback => params[:jsoncallback] }
    end
  end

In your routes.rb you should then have something similar to this:

resources :public_company_profiles do
    get :widget, on: :member
  end

then the JQuery parts making your html code from your JSON informations the third party website will use: First the script to add the jquery then the actual jquery request.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script>
$.getJSON("http://www.yourwebsite.com/yourcontroller/ID/widget?jsoncallback=?",
    function(data) {   
    var logo_url = "http://www.yourwebsite.com" + data.url;
    $("#logo img").attr('src',logo_url);
    $("#logo img").attr('alt',data.company.name);
    $("#name").html(data.company.name);
    $("#desc").html(data.company.description);
  });
</script>

Then it works baby ! (dont forget to put the and stuff around the jQuery documentation here: api.jquery.com/html)

kulssaka
  • 226
  • 8
  • 27
  • That's much better approach mate! You might want to drop respond_to block and use just `render :json` – Eru Oct 17 '12 at 22:40
0

Why are you using render_to_string? Have you tried just plain render?

Also, maybe try making your GET call append .json to the end of the URL.

RonanOD
  • 876
  • 1
  • 9
  • 19
  • render_to_string is used here to pass the partial embed in text to be rendered by the javascript in the third party website. I'm not quite sure where you want me to append the '.json' . I tried to put it in my GET call as followed without result. `` ? not working – kulssaka Oct 15 '12 at 16:09
  • About render_to_string I could choose not to use it and write directly with document.write in the javascript, but I preferred to separate the files. I also check the content of @content, and it was ok :) I followed this for this choice: http://aymeric.gaurat.net/2010/how-to-build-your-own-widget-in-ruby-on-rails-in-10-minutes/ – kulssaka Oct 15 '12 at 16:17