fabriciols
fabriciols

Reputation: 989

django - change content inside an iframe

I have a site running in django and want to make it available on third party sites.

In these sites they make my content available through an tag.

When my site is requested from within that iframe I would like to modify the content (remove header, filter data, etc.).

What would be the best way to do this?

Is there any way of knowing that the request is being made from an iframe?

Multiples sites will request the same url, can I change the content, based on the requesting site?

Thanks!

PS: Sorry for my bad english :/

EDIT

ok, i got it. but i have another questions :

1- How do i tell to my page links (a href) to append "thirdparty" sufix ? is best to change all my links to "relative" paths ?

2- I want to do in a way that some pages will only need the global changes (remove Header/Footer) and some others need special content. Have a way to do this in my context processor ?

thanks !

Upvotes: 1

Views: 3552

Answers (2)

dsalaj
dsalaj

Reputation: 3207

I might have an alternative for cases where using different urls is not an option (ex. when using lightbox to open a link in iframe, but when opening in a new tab the same link has modified content).

I solved my problem by adding the following script to the template of the pages that may be loaded in the iframe:

<script type="text/javascript">
    function inIframe () {
        try {
            return window.self !== window.top;
        } catch (e) {
            return true;
        }
    }
    if(inIframe()) {
        $('header').css('display', 'none');
        $('footer').css('display', 'none');
        // or anything else you may want to do
    }
</script>

Upvotes: 2

cethegeek
cethegeek

Reputation: 6394

One thing you could do is have two mapped URLs: one for use by third parties and one for use by your stand-alone django site.

Both URLs would map to the same django view, but pass a different parameter indicating that you want the full version of the template for the view or a restricted one without header, footers and other parts of the template that third parties would not be interested in.

Use template inheritance or composition (some people will bark at using the include tag, but I always mention it because it is an option) to create appropriate templates - one with all the components for your stand-alone django site and one with just the content third parties are interested in; and have your views use one or the other according to the parameter passed in by the mapped url.

So, third parties would use a url like http://blah.com/thirdparty/abc/12, where /thirdparty/abc is the url for third parties; while your main django site would use http://blah.com/abc/12, where /abc is the url for the stand-alone site. You can have both map to the same view and use extra-options to pass a parameter to the view indicating what template to use.

I think trying to solve the problem by identifying the where the request is coming from is a losing proposition.

Hope that helps.

PS. Your English was perfectly understandable.


Edit:

Suggestion on StackOverflow use: if you want someone to elaborate their answer, add a comment to their answer. That will make StackOverflow note in the little e-mail icon at the top of the page that there is an answer the user should check. I only noticed your edit of the question because I was checking on a spelling error in my response. :-) Edits to the question should be done to clarify the question, sure, but always think if the clarification is generic or if it is a comment to an answer - sometimes you need to do both! Clarify your question and add a comment to an answer to alert the respondent of the change.

Back to the question at hand:

Your urls.py should look something like this:

from django.conf.urls.defaults import *

urlpatterns = patterns('app.views',
    (r'^standalone/(?P<template>\w+)/(\d{4})/$', 'view_callable'),
)

So, one of the parameters captured and sent to the view callable (that I imaginatively called view_callable) is "template" with an indication of a template to use.

Now you have two options:

a) Build two templates using inheritance - so one has no header/footer and a second one, inheriting from the first, adds the necessary extras - and have the view decide which template to render based on the template parameter from urls.py. With this mechanism, each template knows to add the proper template type in the URLS it builds. So templates including header will build urls passing a "complete" or "inapp" indicator as a "template" parameter to urls.py.

b) Build one template using composition - so the template conditionally includes header and footer depending on a parameter passed in from the view, which in turn decided to set the parameter based on the template parameter from urls.py. With this mechanism, the template knows to add the proper template type in the URLS it builds by looking at the parameter set by the view.

The advantage of a) is that you can build completely different looks for your stand-alone and third party templates. Also, if you are going with two templates, it might be advantageous to break urls.py in two urls per view; like:

from django.conf.urls.defaults import *

urlpatterns = patterns('app.views',
    (r'^standalone/standalone/(\d{4})/$', 'view_callable', {'template':'complete'}),
    (r'^standalone/thirdparty/(\d{4})/$', 'view_callable', {'template':'thirdparty'}),
)

This will enable you to do reverse() calls in views or url calls in templates and build links dynamically.

The advantage of b) is that you only have one template to maintain. No risk of updating one and forgetting about the other.

To answer your second sub-question I think I'll need an example to understand what you mean...

Mind that there are probably other ways to do this. This is just the way I thought of.

Upvotes: 2

Related Questions