You are on page 1of 90

Pinax Long Tutorial

PyCon 2010
Introduction
~10 minutes
Who are we? - James Tauber

Pinax Founder

CEO of Eldarion

http://jtauber.com
Who are we? - Daniel Greenfeld

Pinax Core Developer

Software Engineer for NASA's Science Mission Directorate

Author/Instructor for Holden Web, LLC (holdenweb.com)

Developer for Eldarion

http://pydanny.com
Tutorial Prerequisites

• Basic understanding of Python

• Basic understanding of Django

• Laptop

• Python 2.5.x or 2.6.x


History of Pinax

2008: James Tauber decides to stop repeating himself


0.5 — First official release

2009: First full year of Pinax


0.7 — Groups, Static Media, Move to pip and virtualenv,
Section 508

2010: Today
0.9 — Next great thing
Philosophy of Pinax

By integrating numerous reusable Django apps to take care of


the things that many sites have in common, it lets you focus
on what makes your site different.

In other words...

Don't Repeat Yourself


What will we be doing?

Installing Pinax

Reviewing the core underlying layer

Changing the look and feel

Various Pinax tricks

Building on what Python and Django gives us

Deployment

Community
Pinax Installation

~10 minutes
Where to get Pinax

• http://pinaxproject.com/download/

• USB key with bundle


virtualenv

• Ian Bicking

• Isolates all Pinax components from your global environment

• virtual environments is used for dependency control

• You can use multiple virtualenv/pinax-env

• http://pypi.python.org/pypi/virtualenv
pip

• Ian Bicking

• pip is a replacement for easy_install

• All packages are downloaded before installation. Partially-


completed installation doesn't occur as a result.

• Supports requirement files for consistently creating


environments of many packages.

• http://pypi.python.org/pypi/pip
Core Underlying Components
~10 minutes
Core: Accounts

Avatar
Email Addresses
Language
OpenID
Password Management
Signup
Timezone
Sign Up Options

Closed Sign Up

Private Beta

Optional email confirmation


Core: Groups

Groups in Pinax are containers with user


membership and content.

They are a base on which to write your own app


and plug in whatever content apps you need.

Examples:
Tribes (Wiki, Photos)
Projects (Tasks, Wiki)
Guilds (Events)
Core: Static Media Handling
css, images, javascript

Project vs Pinax Theme vs App level

Separation of static media from user-contributed


media.

build_static management command for


deployment
Pinax Projects
~10 minutes
Overview of the starter projects

boilerplate code

scaffolding to get started more quickly

already integrated apps


Examples:
• basic_project
• social_project
• code_project
• company_project (NEW)
Using pinax-admin

List all the currently available projects in Pinax

pinax-admin clone_project -l

Cloning a project

pinax-admin clone_project social_project djangofans


What is in a Pinax project?
• apps directory

• media directory

• slightly extended manage.py

• requirements.txt with project dependencies required


to run

• deploy directory for modpython, fastcgi, and wsgi.

• templates directory with the blocking done

• tests directory to help push you to test.


Pinax specific settings.py
~5 minutes
Some Pinax Settings

SITE_NAME (used in some default templates)


CONTACT_EMAIL (used in some default templates)

PINAX_THEME (prefix for template resolution)

ACCOUNT_OPEN_SIGNUP (can anyone join?)


ACCOUNT_REQUIRED_EMAIL (is email address required?)
ACCOUNT_EMAIL_VERIFICATION (must email be verified?)
EMAIL_CONFIRMATION_DAYS (how long before expiry?)

LOGIN_REDIRECT_URLNAME (first page to go after login)


Media/Static Files Settings
MEDIA_URL / MEDIA_ROOT
   (URL and filesystem location for files uploaded/stored by Django
only)

STATIC_URL / STATIC_ROOT
   (URL and filesystem location for site assets such as CSS, JS and
images)

SERVE_MEDIA
    (Used in urls.py to hook-up MEDIA_URL and STATIC_URL used
for development)
local_settings.py

Good place for environmental settings such as:

    Databases
    
    Debug

    Media locations
Modification of core 
Pinax applications
~10 minutes
Profiles

Frequently extended application

You always want a custom field


Modification of core Pinax applications

Before you change a core application:

Can you accomplish your tasks with CSS?

Can you accomplish your tasks with Javascript?

Can you accomplish your tasks with template changes?

Can you create a new application that does the work?


But my task needs a code/database change!

Don't make changes in Pinax itself!


pinax-env/lib/python2.x/site-packages/Pinax/pinax/apps/<app>

pinax-env/src/Pinax/pinax/apps/<app>
But my task needs a code/database change!

Option 1: Use the apps directory of your project

cd apps/
django-admin.py startapp profiles

Option 2: Use virtualenv/pip

Create a stand alone app (best done eggified)


pip install -e my-app
Adding Django applications
~10 minutes
Won't conversion be hard?

Remember: Pinax is just Django with an opinion

pip install <django-app>

(Don't forget to add it to your requirements.txt file)

make changes to INSTALLED_APPS, etc in settings.py


make template changes
Modification of templates
~10 minutes
Customize templates, don't change them

cp -r site-packages/pinax/templates/default/profiles my-project/templates

Don't edit the Pinax templates directory!


Themes in Pinax

Change your look and feel by just changing settings.py! 

PINAX_THEME = "default"

But only one theme is currently shipped with Pinax

PINAX_THEME = "default"
Changing the logo

Step 1: Add your image to <my-project>/media

Step 2: In <my-project>/templates/site_base.html in
the logo_link_image block change the name of the logo
image to match your own.

(but really you should be making more style changes than just
the logo)
Handy Pinax template blocks

• head_title

• extra_head

• extra_body
Loads after main body. Good for custom Javascript
    
• footer
Changing the look and feel
~10 minutes
base.html versus site_base.html

If you are writing a theme to be used across multiple sites, you 

should modify base.html, not site_base.html.

If you want to keep a particular theme but modify content for a 

specific site, you should modify site_base.html.


Adding and removing tabs
1. In site_base.html add a new li in the right_tabs block.
Make sure that li has and id specific to that to that tab,
e.g. tab_myapp
2. Create a myapps/base.html template that all pages under
that tab will extend. Make sure it defines a
block body_class with contentmyapp
3. edit the CSS file (site_tabs.css if it exists) and at the
appropriate points add the selectors:
o body.myapp #tab_myapp
o body.myapp #tab_myapp a

see http://pinaxproject.com/docs/dev/tabs.html for more


information
Adding CSS

In templates/site_base.html {% block extra_head_base %}:

    <link rel="stylesheet" href="{{ MEDIA_URL }}custom.css" />

mkdir site_media
mkdir site_media/media
touch custom.css

body {
    background-color: #000;
}
Changing Avatar defaults
~10 minutes
django-avatar by default uses Gravatar

Pros:

Gravatars follow a user's account name across the Internet

Means users get a default avatar anywhere

Cons:

You might not want the default Gravatar avatar image

You might not want to lock user avatars into a single service
Changing the default Gravatar logo

In settings.py

AVATAR_DEFAULT_URL =  STATIC_URL + "<our_custom_avatar.jpg>"


AVATAR_GRAVATAR_BACKUP = False
django-groups

~10 minutes
What are groups?

Groups in are containers with user 


membership and content.

Example:

A project with tasks and wiki

A guild with a forum and events


What does django-groups give you?

• Base model on which to build your group app

• A way to do all your URL routing so you get to


the right content objects for the group.

• Nested group support (group apps can be content


object apps at the same time)
Creating a group app

• Adding content objects is simple:

    from groups.bridge import ContentBridge


    bridge = ContentBridge(Project)
    urlpatterns = patterns("", ...) # URLs for the group views
    urlpatterns += bridge.include_urls("topics.urls", r"^project/(?
P<project_slug>[-\w]+)/topics/")

• Group model interface is simple:


o member_queryset (needed if member m2m is named
other than members)
o user_is_member
o get_url_kwargs
Creating content object apps

• Most bits must be aware of group association. Views, forms,


model and template context.
• By 0.9 most all major apps will support group protocol for
content apps.
• Apps don't need to depend on django-groups
• Protocol bits of note
o ContentBridge
 get_group
 reverse
o Group model instance
 content_objects(Model, [join=[...]])
o Template context
 {% extends group_base|default:"site_base.html" %}
Looking at django-groups
pinax-admin clone_project sample_group_project sgp
cd sgp
python manage.py syncdb
python manage.py runserver
django-uni-form

~10 minutes
What is Section 508?

• Rules for making technology theoretically accessible by


individuals with disability.

• Easy to implement if you know how.

• Unfortunately doesn't actually force software to be accessible


to the disabled.

• Enforceable across all government agencies or organizations


accepting money from government agencies.
Why do we care?

• US Government work requires it.

• Disability software is said to be a $170 billion a year industry.

• Open source tends to support accessibility/usability well.

• Its the right thing to do!


Django forms rock!
Tables are for tabular data
In Section 508, some tabular forms are allowed
Out of the box pretty Django forms are tabular
Django Uni-Form =

Django forms docs + template tag +


Uni-Form css/js forms library
Basic Usage
Advanced Django Uni-Form

~10 minutes
Making form generation easier

{% load uni_form_tags %}
{% with form.helper as helper %}
{% uni_form form helper %}
{% endwith %}
Adding action handlers

{% load uni_form_tags %}
{% with form.helper as helper %}

{% uni_form form helper %}

{% endwith %}
Media Handling

~10 minutes
Static Files

css, images, javascript

Separation of static media from user-contributed


media.

build_static management command for deployment

STATIC_URL context variable

SERVE_MEDIA for development


Static media is good

Caching

Security

Separating servers
build_static tool

python manage.py help build_static

Copy static media files from apps and


other locations in a single location.

--dry-run (don't copy but show what will be done)


--link (create symlinks rather than copy)

Project vs Pinax Theme vs App level


STATIC_URL

TEMPLATE_CONTEXT_PROCESSORS = [
    "staticfiles.context_processors.static_url",
]

(be sure to use RequestContext)

<link href="{{ STATIC_URL }}css/polls.css" rel="stylesheet"


type="text/css" />
STATICFILES_DIRS

• Defines resolution order for static media handling

    STATICFILES_DIRS = [
        os.path.join(PROJECT_ROOT, "media"),
        os.path.join(PINAX_ROOT, "media", PINAX_THEME),
    ]
Serving Static Files During
Development
from django.conf import settings

if settings.SERVE_MEDIA:    
 
urlpatterns += patterns("",         
    (r"", include("staticfiles.urls")),     
)
JavaScript, jQuery and Pinax

~5 minutes
Why was jQuery chosen for Pinax?

Because Pinax has an opinion

But you can still use YUI, Mootools, or plain old JavaScript
Best practice for JavaScript use
django-ajax-validation

~5 minutes
django-ajax-validation

In urls.py:

    from my_app.forms import MyAppForm

    (r"^validate/$", "ajax_validation.views.validate", {
        "form_class": MyAppForm,
        "callback": lambda request, *args, **kwargs:     
            {"user": request.user}
    }, "myapp_form_validate"),
django-ajax-validation

in templates/my-app/edit.html:

{% block extra_body %}
    {% load jquery_validation %}
    {% include_validation %}
    <script type="text/javascript">
        $(function(){
            $('#myapp_form').validate('{%
url  myapp_form_validate %}', {type: 'uni_form'});
        });
    </script>
{% endblock %}
django-pagination

~2 minutes
django-pagination
{% load pagination_tags %}

...

{% autopaginate results 10 %}

...
        
{% paginate %}

style with CSS:


.pagination, .page, .page.selected, .page-prev, .page-next
Testing your Pinax application

~5 minutes
Why should you bother testing?

"Untested code is broken code"


Martin Aspelli

"Code without tests is broken as designed"


Jacob Kaplan-Moss

"All the cool kids are doing tests"


Chris Shenton

"If I go to another testing talk I'm going to die"


Daniel Greenfeld
Pinax Deployment

~10 minutes
What Pinax gives you

• Each project has a deploy/ directory

• deploy/ contains working mod_wsgi, FastCGI and


mod_python deployment files.

• Much of Pinax has been designed to be a simple


deployment with the way we've constructed settings.
Example Apache config

<VirtualHost *:8001>
    ServerName eldarion.com
    
    WSGIDaemonProcess eldarion.com user=eldarion group=eldarion processes=1
threads=25 python-path=/home/eldarion/virtualenvs/eldarion_project/lib/python2.5/site-
packages
    WSGIProcessGroup eldarion.com
    
    WSGIScriptAlias /
/home/eldarion/webapps/eldarion.com/eldarion_project/deploy/pinax.wsgi
    <Directory /home/eldarion/webapps/eldarion.com/eldarion_project/deploy>
        Order deny,allow
        Allow from all
    </Directory>
    
    ErrorLog /var/log/apache2/eldarion.com.error.log
    LogLevel warn
    CustomLog /var/log/apache2/eldarion.com.access.log combined
    
</VirtualHost>
Things to remember when deploying

• Setup cron jobs for clearing mail queue and notification


queue

• Recommended to create a maintenance.wsgi script that you


can simply cp over pinax.wsgi to take the site down for
deployment (don't forget to actually do this)

• Always remember to run build_static before claiming your


deployment is complete
Community

~10 minutes
How to communicate

1. Don't be 'that guy'.

2. Be friendly.

3. Be patient.

4. Tell us your operating system and version of Python.

5. Use a pasting service for code or shell statements:

    dpaste.de
    code.pinaxproject.com
Finding Help

Documentation:

    http://pinaxproject.com/docs/0.7/
    http://pinaxproject.com/docs/dev/

IRC:

    #pinax

Mailing List:

    http://groups.google.com/group/pinax-users
Contributing back

http://code.pinaxproject.com

    Task tracker and wiki for the Pinax project

    Search the tickets before creating a new ticket

http://github.com/pinax/pinax

    Fork and submit pull requests

    Tests and documentation are required

    Documentation must be in restructured text


Contributing back - Modular Efforts

For stand-alone Django or Python efforts:

    Documentation and tests are required

    Make your work modular and easy to use

    Put your finished work on PyPI


Q&A

You might also like