I have a facebook timeline page tab app that's running inside an IFRAME on a fan page.
On the main page of the app, we show 10 jobs and users can click through to the detail page of one single book.
We want to add a LIKE button on those detail pages, so that users on facebook can like and share that job in their stream.
The app is totally dynamic so different customers can install the app on their fan page and list their own jobs. (ex. coca-cola installs it on his coca-cola page and lists jobs within the company. then microsoft installs it as well and does the same)
The problem concerns og:metatags and redirection of the liked detail page link, right inside the right facebook company page and relative right detail page showing the job.
I can get these two things done and working but not at the same time:
A. Facebook gets correctly the og:metatags in the head section, with image, title, description when I use the following implementation of the like button (without "data-href" extra attribute)
<div class="fb-like"
data-send="false"
data-layout="button_count"
data-show-faces="false"
data-action="like"
data-font="arial">
</div>
The problem is that not specifying the data-href attribute (and the og:url meta is totally ignored) this is gonna create a link to the current page => intended current page inside an iframe => so the result will be that when you click the shared job on facebook you will be redirected NOT inside the facebook app -right page -right detail page, but to the detail page on the server that hostes the app.
B. If I instead specify the data-href attribute
<div class="fb-like"
data-href=<%= "http://www.facebook.com/pages/:page/#{session[:fb_page_id]}?v=app_XXXXXXX&app_data=#{#job_details.job_id}" %>
data-send="false"
data-layout="button_count"
data-show-faces="false"
data-action="like"
data-font="arial">
</div>
Doing this I can get the right link posted on facebook (so then using &app_data attribute) I can get the perfect redirection working.
BUT on the downside, the og:metatags are totally ignored and instead facebook picks the page tab metatags (top iframe that hostes the pagetab app) and so I get posted on facebook a crap link that tells about a page on facebook with the page app picture. And the even bigger downside is that when you like a job on the app, all the jobs appear to be liked as well (basically the iFrame app becomes the liked page... instead of being the job detail page picked as liked page)
Is out there any genius that knows how to sort this out? I need to get the A an B working at the same time to get the requested result!!!!
Please help!!! :(
I've found the solution myself.
Like button => use href and ref attributes, especially put on the ref the id of your facebook fan page. Passing the current page url will also load and share correctly the og:metatags.
<div class="fb-like"
data-send="false"
data-show-faces="false"
data-layout="button_count"
data-font="arial"
data-action="recommend"
href=<%= "https://app.com/jobs/job_details.job_id" %>
ref=<%= FB_PAGE_ID %>>
</div>
Once you pass the ref attribute to facebook, on your wall the link will be posted by facebook with an extra query string appended with in particular the "fb_ref" parameter:
for example a button with parameters:
href=<%= "https://app.com/jobs/job_details.job_id" %>
and
ref=<%= 332325142248470 %>
becomes:
https://app.com/jobs/a0Ed000000a54bkEAA?fb_ref=332325142248470&fb_source=profile_multiline
when the user clicks the link we want to be redirected back right inside the correct page tab app and right job details page. To achieve this we set up into the controller/show action (that in ruby corrisponds to controller_name/id) a new redirection, remembering that ref will put inside a query string after our href link:
if params[:fb_ref]
redirect_to "http://www.facebook.com/pages/:page/#{params[:fb_ref]}?v=app_xxxxx&app_data=#{params[:id]}"
end
As you can see we create a new dynamic url that will use the "app_data" parameter of the facebook "signed_riquest" (http://developers.facebook.com/docs/authentication/signed_request/) in order to pass to our application the right detail page to be visualized and also redirect us to the right facebook page.
once done this we have just to manage correctly the new app_data parameter that comes now with the signed_request. In my case in one of my main controller I've used:
if fb_signed_request[:app_data]
redirect_to "/jobs/#{session[:app_data]}"
end
And we will see our app loading the right page and the right job detail page!
Hope is gonna help other people!
Related
Trying to grok this e-commerce scenario...
I build an amp product page in amp that has the new amp-form
The add to cart button is an XHR to my backend (that is session based, using
cookies by default)
User searches for product and results take them
to my amp product page, but they've never been to my site
They submit the add to cart form
the CORS preflight makes it's way to my backend, and i set all the correct allows as per https://github.com/ampproject/amphtml/blob/master/spec/amp-cors-requests.md
Now the actual request is made... backend initializes a session,
returns session identifier as a cookie, but since user never went to
my site...just the google amp cache it's treated as a 3rd party
cookie and browser discards it (cause user disables 3rd party cookies)
users session is lost, as is their add to cart action
So the question is, how do i keep the session around and the item in the cart?
Am i missing something? is there a trick i'm not seeing?
appreciate any insights.
Associating the shopping cart with the CLIENT_ID would be the best way to solve this problem. Unfortunately, transferring the CLIENT_ID via forms is not yet supported in AMP. It's currently being implemented, you can watch this issue for the current status.
Here is an approach that works right now: the idea is to encode the shopping cart content into a string that is returned in the form result. This way we can generate "View Cart" and "Checkout" links including the shopping cart content. Once the user clicks on one of those links, you can create the actual shopping cart in your backend and store the user id in a cookie.
For example:
<form action-xhr="/add-to-cart" method="POST">
<input type="hidden" name="itemId" value="headphones-123">
<!-- Hide after form submit success -->
<input type="submit" name="add" value="Add to Cart">
<div submit-success>
<template type="amp-mustache">
<!-- shopping cart contents, e.g headphones-123 -->
{#shoppingCartContent}
View In Cart
Checkout
{/shoppingCartContent}
</template>
</div>
<div submit-error>
<template type="amp-mustache">
{{message}} <!-- e.g. Only 2 Headphones are left. -->
</template>
</div>
</form>
The disadvantage of this approach is that the shopping cart will be lost when the user leaves the page without viewing the cart first. This will be solved once the CLIENT_ID can be passed via amp-form.
I also know very limited info about AMP pages but I suggest that you please read through the use of User identification and try using an AMP-generated client ID. As mentioned in the documentation:
By default, AMP will manage the provision of a client ID whether the page is accessed from the publisher's original website or through a cache.
Likewise, learn more about client ID substitution, including how to add an optional user notification ID, in Variables supported in AMP analytics.
Hope that helps!
I am trying to solve an issue with modals. What I want to do is allow the user to click the browser's back button to dismiss a modal and return to the original state of the page, this is: without modal. For such purpose I thought about using HTML 5 history API.
I started trying to append a querystring parameter to the URL, such as http://...page.html?show_modal=[yes|no] but I ended leaving this approach because I couldn't handle all the stuff involving popstate event, pageshow event, etc. I couldn't make it work and it overwhelmed me.
Then I tried with a more simple approach involving a hash appended to the URL, such as http://...page.html#modal, and the hashchange event. This approach is working better for me and I almost have it.
When the user clicks the button to show the modal, he or she can click the browser's back button and it will dismiss the modal. Furthermore, after that, the user can click the browser's forward button and it will show the modal again. Very nice! The user can also navigate directly to the URL with the hash to access directly this state of the page, as well as he or she can bookmark such state of the page. It's working pretty neat and I'm rather happy with the results.
The problem is that it is not working totally perfect. When the user dismiss the modal by clicking the background, the ESC key or the X in the upper right corner, the history starts to mess up. Try it: open the modal by clicking on the button, then click the background to dismiss it (look a the URL in the address bar, first problem here is that the hash isn't removed), then click your browser back button and you will see it isn't working correctly. You will end with a duplicate in your history and you have to click the back button twice in order to go to the previous page. This is not desirable from an UX viewpoint. Does anyone know a solution to this?
I provide my code in this CodePen and at the end of this question. I suggest trying it in your own machine and NOT IN Codepen, so you can view the hash in the URL, etc. Also, it doesn't work in Codepen Full mode, I don't know why.
Thanks!!
I am using Foundation 5.2.1
HTML
<div class="row">
<div class="small-12 columns">
<h1>Reveal Modal</h1>
<h2>Manipulation of the browser history for a better UX</h2>
<a class="button radius" href="#" data-reveal-id="sampleModal" id="button">Show Modal...</a>
</div>
</div>
<!-- ############# -->
<!-- MODAL -->
<!-- ############# -->
<div id="sampleModal" class="reveal-modal medium" data-reveal>
<h2>Hi!</h2>
<p>You may think you are on a new page now, but you aren't. Try to click your browser <kbd>Back</kbd> button to dismiss this modal and return to the the page you were viewing.</p>
<a class="close-reveal-modal">×</a>
</div>
JavaScript
function setModalHash(url, present) {
var a = $('<a>', { href:url } )[0]; // http://tutorialzine.com/2013/07/quick-tip-parse-urls/
var newHash = "";
if (present === true) {
newHash = "#modal";
}
// Build the resulting URL
result = a.protocol + "//" + a.hostname + ":" + a.port + a.pathname + a.search + newHash;
return result;
}
$("#button").on('click', function() {
history.pushState(null, null, setModalHash(document.URL, true));
});
$(window).on("hashchange load",function(e) {
// Handling also the load event allows navigation directly to http://host/path/to/file#modal and bookmarking it
if (document.location.hash == "#modal") {
$("#sampleModal").foundation("reveal","open");
}
else {
$("#sampleModal").foundation("reveal","close");
}
});
I've been messing with the history api/History.js in combination with session storage to maintain modal state, and open/close based upon user navigation. I've finally achieved about 90% of my goal, but history is implemented very poorly in Safari and iOS Safari so remove the features for these browsers.
Some of the problems you may be running into with the hash approach is that when you use the # with pushstate it actually doesn't push a new object into the history state. It sometimes seems to push history onto the stack and you could use history.back() to fire a popstate, but if you were to say refresh the page with your hashurl and do some sort of check for hash on page initiation, there doesn't seem to be a new history pushed onto the stack, and therefore on backwards navigation the user will leave the site rather than closing the modal.
Here is my implementation working for all browsers except for where it falls back to normal behavior is Safari:
http://dtothefp.github.io/hosted_modal_history_sample/
https://github.com/dtothefp/html5history_express_modal_toggle
Like I said I use History.js in combination with sessionstorage because annoyingly enough, in the popstate for closing the modal the history object is removed, which is exactly when I would need it. In all a very poorly implemented API.
I don't change the URL because this project does not have a backend, so if I change the URL with no hash, on page refresh the page would not be found. An alternate implementation would be a query string, which will properly update history when used in the pushstate, but ends up being bad UX because if the user closes the modal not using the backwards navigation (i.e. hitting the cancel button or clicking off), removing the query string would result in a page refresh.
The site is: http://grantdeb.com
I want to be able to dynamically add meta properties to the Recommend(s) and Send(s). Right now, it's using the meta og: properties and that is totally NOT what I want.
The LIKE count is also showing incorrectly for each like even though I've pushed the data-href to it like:
<div class="fb-like" data-href="http://grantdeb.com/wedding-photographers-hampton-roads/[dynamic id]/Wedding-Photography" data-send="false" data-width="450" data-show-faces="false" data-action="recommend" ></div>
BUT - for some reason, once in a while the LIKE / SEND does NOT use the meta properties and correctly shows the correct count AND the correct picture / title I want for the Send.
If you go to our site at http://grantdeb.com look specifically at the "Jasmine Plantation Wedding Photography" (like the 5th post down) you'll see the number of Recommendations is correct, and if you hit the "Send" button at right bottom, it actually uses the correct title and picture we want.
That post is the way we want the Recommend / Send to display.
Why is that happening to some of them and to others it shows our og: metadata?
I can’t exactly see on your site what the problem is (or match your problem description with your site’s content) – but looking at the URL for the post you mentioned in Facebook debug tool, it seems that you have
<meta property="og:url" content="http://grantdeb.com" />
set for all of your detail pages – so that is what Facebook considers the “real” URL for all of your actual posts marked with this tag.
(Can’t tell if this is what you explicitly wanted or not, because your problem description is kinda fuzzy to me.)
I posted the following in my blogger page to add individual Facebook "likes" to each post -
<script>
document.write('<iframe src="http://www.facebook.com/plugins/like.php?href=<data:post.url/>&layout=standard&show_faces=false&width=380&action=like&font=trebuchet+ms&colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px; height:25px"></iframe>');
</script>
After clicking "like" in specific post, such story will also appear on the timeline of the one who clicked "like". However, the thumbnail is not working.
http://img.photobucket.com/albums/v369/q_quincyluk/fb_like_bug.jpg
How can my pictures in individual posts be shown as thumbnails?
You're probably missing the og:image meta tag on the post which tells Facebook which image to use
Run your page through the debugger at https://developers.facebook.com/tools/debug to see which tags you're missing and/or what Facebook is detecting for each URL.
I have a web page where the user enters some data and then clicks a submit button. I process the data and then use the same Django template to display the original data, the submit button, and the results. When I am using the Django template to display results, I would like the page to be automatically scrolled down to the part of the page where the results begin. This allows the user to scroll back up the page if she wants to change her original data and click submit again. Hopefully, there's some simple way of doing this that I can't see at the moment.
It should already work if you provide a fragment identifier in the action method of the form:
<form method="post" action="/your/url#results">
<!-- ... -->
</form>
and somewhere below the form, where you want to show the results:
<div id="results">
<!-- your results here -->
</div>
This should make the page jump to the <div> with ID results.
It is complete client site and does not involve Django, JavaScript or similar.
You need to wrap your data into something like this:
<div id="some-id">YOUR DATA TO BE DISPLAYED</div>
and if you make redirect in your view you need to redirect to url: /some-url/#some-id
if you don't make redirect you need to scroll to the bottom using javascript (but note that redirect is preffered way to use in view after saving data).