Facebook app with an iframe on rails - ruby-on-rails

I'm attempting to create a facebook app and went through the book http://pragprog.com/titles/mmfacer/developing-facebook-platform-applications-with-rails. Everything works fine on my development machine when I have my canvas render method set as fbml. But, for various reasons I want to build an app with an iframe. When I set my app to use an iframe I am unable to connect to my development machine. I went through a lot of different articles about creating an iframe app, but none seem to work. That includes
http://wiki.developers.facebook.com/index.php/Cross_Domain_Communication_Channel
http://wiki.developers.facebook.com/index.php/XFBML
and any other site found googling any combination of facebook, iframe, rails and others.
I have the xd_receiver.htm file in my public directory and my layout looks like
<!doctype html public “-//w3c//dtd xhtml 1.0 strict//en” “http://www.w3.org/tr/xhtml1/dtd/xhtml1-strict.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” xmlns:fb=”http://www.facebook.com/2008/fbml”>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title><%= controller.controller_name %>: <%= controller.action_name %></title>
<%= stylesheet_link_tag "jquery-ui-1.7.1.custom.css", "styles" %>
<%= javascript_include_tag "jquery-1.3.2.min.js", "application" %>
</head>
<body>
<%= yield %>
<script src="http://static.ak.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>
<script type="text/javascript">
FB_RequireFeatures(["XFBML"], function(){
FB.Facebook.init("my api key", "xd_receiver.htm"); });
</script>
</body>
</html>
My question is, what am I missing that is preventing facebook from connecting to my rails development machine when I set the canvas render method to iframe? Since my development log does not show any attempts of a connection, I'm guessing that it has something to do with the cross domain stuff, but I can't find a good answer about it anywhere.

If you place that file under /public, its important to note that the ERB contained within the template will not get parsed as you expected. I'm not too familiar with the plugin you are trying to use but have used the Facebooker gem (http://facebooker.rubyforge.org/) which provides a tidy way to interact with the Facebook REST API.

I strongly suggest using Facebooker from the beginning.
It'll save you a lot of time.

/xd_receiver
there are facebooker methods for this sort of thing check this out
http://blog.yangtheman.com/2009/08/23/how-to-integrate-facebook-connect-with-a-rails-app/

Related

Workaround for #request.getParameters() in Thymeleaf

We are using CAS 5.2.3 which uses an upgraded version of Thymeleaf. Thymeleaf has restricted access to certain request features - '#request.getParameters()' being one. Is there any work around for it? I am getting the following error when trying to access it - "Access to request parameters is forbidden in this context. Note some restrictions apply to variable access. For example, direct access to request parameters is forbidden in preprocessing and unescaped expressions, in TEXT template mode, in fragment insertion specifications and in some specific attribute processors."
Good question. I face this problem a few months before, it is solvable.
After looking through their source code, I found that they are limiting the usage of #request.getParameters() only on specific tag, they didn't forbid to use #request.getParameters() in some situation.
In my use case, I am able to use CData to bypass this checking. Not sure whether it applies to your use case since you didn't provide any code example....
Anyway, the below example want to redirect user to another page, based on the parameter url
Here's an sample code that was broken in CAS 5.2.x, but worked in CAS 5.1.x :
<html>
<head>
<title> Deforestation </title>
</head>
<body th:attr="onload='window.location.href=\''+${#request.getParameter('url')}+'\''">
</body>
</html>
Here's a work around code:
<html>
<head>
<title> Deforestation </title>
</head>
<body>
Logging out. Please wait...
<script th:inline="javascript">
/*<![CDATA[*/
location.href = /*[[( ${#request.getParameter('url')} )]]*/ ;
/*]]>*/
</script>
</body>
</html>
If this didn't solve your problem, please provide your source code so we can have a better look at the problem.
Note: There is a security reason why this stuff is now banned, using this workaround might compromise the security standard, do remember to sanitize the user input if neccesary
Edit:
as per comment, although not elegant, maybe something like the following will work?
<html>
<head>
<title> Data attribute </title>
</head>
<body>
<span id="foobarid"> </span>
<script th:inline="javascript">
/*<![CDATA[*/
$('#foobarid').data('foo-bar',/*[[( ${#request.getParameter('foo') == 'bar'} )]]*/);
/*]]>*/
</script>
</body>
</html>
Apparently one can spend hours, even days on this simple requirement, which Thymeleaf introduced as a poorly dcumented annoyance in later versions. I've spent hours upgrading from an older Thymeleaf version from 5 years ago and got stuck on this very same problem. The lack of documentation didn't either. When I finally took a think break, I've realized the solution to this problem is as simple as using the <c:set> core tag with JSP.
Simply use the th:with tag in some higher level html tag where accessing request parameters is allowed, like this:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns="http://www.w3.org/1999/xhtml"
th:with="action=${param.action != null ?
param.action[0] : 'none'}">
<head>
...
In this example, the request parameter action is stored in a page context local variable named action (the name can be any unique name that you choose). This variable is now accessible anywhere bellow your high level html tag where you've defined it. It can even be used in following th:xx tags in the same html tag after the declaration. So basically, now you can do this:
<th:block th:switch="${action}">
<title th:case="'edit'" th:text="#{page.contacts.edit}"></title>
<title th:case="'delete'" th:text="#{page.contacts.delete}"></title>
<title th:case="*" th:text="#{page.contacts.add}"></title>
</th:block>
and even call a parameterized fragment by simply referring to your variable as ${action}. In this example I have a navbar template fragment, which accepts three parameters. The last of which, is a request parameter that otherwise, is inaccessible due to the newer Thymeleaf request object access restrictions.
<div id="wrapper">
<div class="nav" th:replace="html/fragments/navbar ::
navbar('html/contact','contact-html', ${action})">
</div>
<div class="content">
...
If you need more request params and more local page context variables, just use a comma to separate the declarations in the th:with tag like this:
th:with="action=${param.action == null ? 'none': param.action[0]},
self=${param.self == null ? 'none': param.self[0]}"
I hope this saves you guys some precious time and voids the frustration of refactoring older Thymeleaf html pages. It definitely beats those horrifically unmanageable CDATA scriptlets inside your pages.

Twitter Bootstrap and Rails: How to make some views responsive and others not

According to the bootstrap docs
adding the following to your <head> makes your site responsive
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="assets/css/bootstrap-responsive.css" rel="stylesheet">
In rails and the asset pipeline you declare your css file in application.css so the last line above is not required.
Im using the bootstrap-sass gem and the above line is achieved this line of code in the application.css file
#include "bootstrap-responsive";
It works!
But unfortunately this makes every view responsive.
I have a number of views such as my backbone app that I dont want to be responsive.
I thought about declaring the <meta viewport...> tag into a layout file that is only used for the those parts of my site that require responsive behavior.
This doesn't seem to work and despite some views not declaring this meta tag via their layout, they still become responsive.
Since I cant granularly control which css files get loaded in the asset pipeline I'm a bit stumped how to turn off and on this responsive behavior.
How do i achieve this?
Check out This link for some good info. It can be overwhelming, know, you don't have to do ALL of that... The key is: if you remove require tree (which will not add all files in directory) you need to manually add them in config/environments/production.rb with:
config.assets.precompile += %w( application-all.css application-print.css application-ie.css )
Then you can use stylesheet_link_tags with no issues...
To make it more flexible I add this to my application head:
<%= yield :head if content_for?(:head) %>
and then all my views use:
<% content_for(:head) do %>
<%= stylesheet_link_tag "#{params[:controller]}.#{params[:action]}" %>
<%= javascript_include_tag "#{params[:controller]}.#{params[:action]}" %>
<% end %>

Where is the optimal place to put an API link in Rails 3.1

I'm trying to figure out the asset pipeline in Rails 3 to play around with the Google api
"http://maps.google.com/maps/api/js?sensor=false"
1st question. Is it best to place that link in views/layouts/application.html.erb or in assets/javascripts/application.js
2nd question
If I'm writing a javascript function that gets its arguments from a form id in a view, where do I put that javascript function? Does it go directly in assets/javascripts/application.js or are there other places to put the javascript..
I am not sure if you even can put the maps API into the application.js. At least it didn't work for me last time I tried.
The general idea of application.js is that all content that is referenced there will be automatically minified and compressed in a production environment. Since that's not possible for the maps API I guess you should put it into your views/layouts/application.html.erb
Also note that you may not want to include the maps API on all your pages. You could either define a layout that is itself referencing application.html.erb or you use a partial or you use a content_for to include the page only in the places you need it.
One thing I've done in the past (there may be better ways) is to define a placeholder in the head section of the layout and then use that to inject scripts that are only required on a small number of pages. Like this:
application.html.erb:
<head>
other stuff
<%= yield :scripts %>
...
</head>
And inside your view that requires google maps:
<% content_for :scripts do %>
<script type="text/javascript" ..... ></script>
<% end %>
Anything inside the content_for block will be output where you placed your <%= yield :scripts %>.

javascript_include_tag output safe html

I've updated http://tetalab.org/ with RefineryCMS 1.0.8, and now, our stylesheets and javascripts are outputted as safe html, breaking anything on the site.
Exemple of code outputting safe html:
<%= javascript_include_tag 'modernizr-min' %>
Code found in html source:
<script src="/javascripts/modernizr-min.js" type="text/javascript"></script>
Could someone provide some tips about this issue?
This is likely because you're using refinerycms-theming plugin.
This plugin does bad things and is not recommended
I think if you removed that the problem would go away :)

Rails - is there a way to get Rails to render a Style .css file inside of the view?

Instead of the page making another request for the CSS, I would like to have the Rails view render the CSS file in the page, so it's only 1 request.
Is this possible?
Altough the typical way to include CSS is using stylesheet_link_tag (in particular so it gets cached by the client), it is possible to put it directly in your <HEAD> in Rails 3.1:
<HEAD>
....
<STYLE type="text/css">
<%= YouAppName::Application.assets["your_stylesheet.css"].to_s.html_safe %>
</STYLE>
</HEAD>
I adapted this from this post.
<%= stylesheet_link_tag :all %> assuming your CSS file is in your public/stylesheets folder (which is the conventional place to store stylesheets). Of course, instead of :all, you can specify a specific file.
in your page's block.
I usually do this in my application.html.erb (which is a layout in your app/views/layouts) folder. But you can do this in any view file with a block.
Good luck!
Just wrap your CSS in
<style></style>
within your view.

Resources