Archive for the 'Css' Category

Django Facebook 2.0 – Integrating Facebook

It’s been a year since Facebook changed the web with the open graph API and their like button. Unfortunately Facebook didn’t have much developer love for the python/django platform. Django Facebook aims to make it easy to build facebook apps and integrate facebook with your website.

Key functionality

One of the strong points of Django Facebook is the ability to register users using Facebook. It ports all of Facebook’s user data to the Django user and profile models. This allows you to have a secure register/connect/login flow using Facebook, greatly reducing the barriers to start using your application. Below an example of me registering for Fashiolista using the Facebook register flow.

Me on Facebook

Me on Fashiolista

In this blog post I will explain how to get started implementing a Facebook connect flow. Django Facebook can however do quite a bit more, as you can see in the feature list below. Development over at the github repo is very active. I strongly appreciate help on improving the functionality so please fork and contribute.

Features

  • Register users using the Facebook open graph API
    • Full profile data birthday, gender, website, about me, username, email and picture
    • Support for mobile authentication
    • Fallback to registration form for entering additional data when required
  • Build Facebook Canvas applications
  • Mobile registration using Facebook
  • Execute Facebook FQL queries
  • Upload pictures to Facebook
  • Find your Facebook friends

Getting Started

Now let’s get started with building a Facebook login/connect/register flow. This post will guide you through it step by step.

Prerequisites

Create a Facebook app

Have django registration installed (other registration systems will require some small code changes)

pip install django_facebook :)

A.) Settings and more

Define these settings in your settings file.
FACEBOOK_API_KEY
FACEBOOK_APP_ID
FACEBOOK_APP_SECRET

add django facebook to your installed apps
‘django_facebook’,
add this line to your url config
(r’^facebook/’, include(‘django_facebook.urls’)),
add this line to your context processors
‘django_facebook.context_processors.facebook’,
add this to your AUTHENTICATION_BACKENDS
‘django_facebook.auth_backends.FacebookBackend’,

B.) Adjust your user Profile model

Secondly we need to be able to store the Facebook data on your user profile.
The easiest way to do this is to add the abstract model in django_facebook/models.py called FacebookProfileModel to your profile model.
After your profile is ready to store Facebook data you should have a working example at /facebook/connect/.
Let me know in the comments if something went wrong up to this point :)

C.) Design and integration

You can style the facebook form and button anyway you see fit. Over at Fashiolista we added a nice facepile for example. The basic markup is located in the example file connect.html.
We use the facebook javascript SDK for a smooth user integration. You can load the facebook JS like this:

<script src="{{ MEDIA_URL }}js/original/facebook.js" type="text/javascript"></script>
<script>
facebookAppId = '{{ FACEBOOK_APP_ID }}';
function facebookJSLoaded(){
FB.init({appId: facebookAppId, status: false, cookie: true, xfbml: true});
}
window.fbAsyncInit = facebookJSLoaded;
F = new facebookClass(facebookAppId);
F.load();
</script>

Subsequently implement a form which calls Facebook via javascript. Note that you can control which page to go to after connect using the next input field.

<form action="{% url facebook_connect %}?facebook_login=1" method="post">
<a href="javascript:void(0);" style="font-size: 20px;" onclick="F.connect(this.parentNode);">Register, login or connect with facebook</a>
<input type="hidden" value="{{ request.path }}" name="next" />
</form>
<div id="fb-root"></div>

That was all, you should now have a working registration flow using Facebook. Let me know in the comments if you encounter any difficulties.
If you want to go one step further and understand the facebook API, you can find the Facebook documentation here.
Django Facebook received tons of improvements from the python community. I’m certainly missing a few authors, but I would like to thank a few specifically:

Many thanks to (amongst many others)

More posts coming up

  • Building a facebook canvas app using Django Facebook
  • Find and invite friends using Django Facebook

We’re hiring!

Do you also see the beauty in clean code? Are you experienced with high scalability web apps? Currently we’re looking for additional talent over at our Amsterdam office. Feel free to drop me a line at my personal email for more information: thierryschellenbach[at]gmail.com

Css & Django & Events & Facebook & Fashiolista & Prototype & Python & Web Development tschellenbach 23 Jun 2011 70 Comments

YTM launch!!

No more beta for YouTellMe.nl
The website which is taking over the Dutch product comparison market is officially going out of beta @ 8 o clock.
Party in Amsterdam, Keizersgracht 182 :) Festivities starting right now!

13342_350348980430_784785430_9966158_5558110_n

Things are going well, looking very forward to international launch.
We’ve changed a lot since the first reviews!

13342_350352790430_784785430_9966172_7726367_n

Beter pictures coming after the event :P

PS. Thanks to Python and Django, for enabling us to beat the competition :)

PSS. Next2News, eduhub, come and join :)

Apache & Business & Css & Django & Dutch & Events & Javascript & PHP & Prototype & Python & Symfony & Web Development & YouTellMe tschellenbach 11 Dec 2009 150 Comments

CSS Vista is great

For those trying to debug their CSS in Internet Explorer (if you still support that browser)

Have a look at CSS vista, it is free and helped me a great deal.

Css & Web Development tschellenbach 10 Nov 2007 Comments Off

Using php to dynamically generate conflict free css

This little blog has been getting a lot of coverage lately thanks to a write up by Ajaxian. Developing with Symfony is great and always gives you a lot to think and write about.

For my new product I was having a CSS conflict. This tends to happen when you include your own html and css into someone else’s website. For instance if you have a widget as such:

html

<div id="mywidget">
<h1>My hello world widget</h1>
</div>

css

H1 {
color:green;
font-size:20px;
}

The solution to this problem is quite straightforward, you simply specify your css selector as div#mywidget H1. However, what if you want to allow people to customize the looks of your widget. Now you could off course ask them to include the div#mywidget part, but chances are this will give problems.

Since I was already using the great sfCombineFilterPlugin an easy solution was available. (If you didn’t use the sfCombineFilterPlugin yet, go check it out immediately. Also have a look at Yahoo’s Yslow)

The sfCombineFilterPlugin uses php to gzip, minify and cache your css and javascript. Here is how to extend that behavior to include the #mywidget specification. (Assuming you have sfCombineFilter installed)

Step 1: open your .htaccess

Just below the RewriteBase instruction add:
# if we are retrieving javascript or css
RewriteRule ^css/packed/prepend/(.*\.css) /sfCombineFilterPlugin/combine.php?type=css&prepend=1&files=$1
RewriteRule ^css/packed/(.*\.css) /sfCombineFilterPlugin/combine.php?type=css&files=$1
RewriteRule ^js/packed/(.*\.js) /sfCombineFilterPlugin/combine.php?type=javascript&files=$1

Step 2: add this class to the top of web/sfCombineFilter/combine.php

Partly based on CSS parser class.

class prependCss
{

    public static function prependCssString($str) {
        // Remove comments
        $str = preg_replace("//*(.*)?*//Usi", "", $str);

        $parts = explode("}",$str);
        if(count($parts) > 0) {
            foreach($parts as $part) {
                list($keystr,$codestr) = explode("{",$part);
                $keys = explode(",",trim($keystr));
                $newkeys = array();
                if(count($keys) > 0) {
                    foreach($keys as $key) {
                        if(strlen($key) > 0) {
                            $key = (!strstr($key, '#mywidget')) ? '#mywidget'.$key : $key;
                            $newkeys[] = $key;
                        }
                    }
                    $keystr = implode(', ',$newkeys);
                }
                if(!empty($keystr)) //needed for spaces behind last }
                $rules[] = $keystr . " {" . $codestr . "}";
            }
            $prependedCss = implode("n", $rules);
        }
        //
        return $prependedCss;
    }

    public static function prependCssFile($filename) {
        if(file_exists($filename)) {
            return self::prependCssString(file_get_contents($filename));
        } else {
            return false;
        }
    }
}

Step 3: hack around in combine.php

below $minify_js add:
if($_GET['prepend']==1)
$prepend = true;

change the stuff below this comment to:
// Get contents of the files
$contents = '';
reset($elements);
foreach ($files as $path) {
if($prepend && $_GET['type'] == 'css') {
$contents .= "\n\n" . prependCss::prependCssFile($path);
} else {
$contents .= "\n\n" . file_get_contents($path);
}
}

And finally just change your urls to css/packed/prepend/yourcss.css (if you are using relative paths in your css you might need to add an ../)

Conclusion

Using this technique your css will load without any problems in third party sites. This comes in very useful when creating widgets or greasemonkey scripts.

Css & PHP & Symfony & Web Development tschellenbach 29 Oct 2007 13 Comments