<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged web</title>
    <link href="https://passingcuriosity.com/tags/web/web.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/web/web.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2017-01-02T00:00:00Z</updated>
    <entry>
    <title>Events in August 2014</title>
    <link href="https://passingcuriosity.com/2017/august-2014-events/" />
    <id>https://passingcuriosity.com/2017/august-2014-events/</id>
    <published>2017-01-02T00:00:00Z</published>
    <updated>2017-01-02T00:00:00Z</updated>
    <summary type="html"><![CDATA[<blockquote>
<p>It’s the beginning of a new year so I’m cleaning out some files in
my drafts directory. This post was started on August 18, 2014.</p>
</blockquote>
<p>In an effort to blog more regularly and to post content that is more mine
than transcriptions of others, I’ll be writing a regular round-up of the
events I attend. To start with, here are a few from the last three weeks.</p>
<h2 id="australian-openstack-user-group">Australian OpenStack User Group</h2>
<p>I’ve recently started working at <a href="http://www.anchor.net.au/">Anchor Systems</a> and sit next to some
of the people working on the new <a href="http://www.anchor.com.au/blog/category/cloud-computing/">Anchor OpenStack cloud</a>, so I’ve
been hearing (and overhearing) quite a bit about OpenStack and OpenStack
deployment recently. One of the things that sounded quite interesting is
“OpenStack On OpenStack” (or “Triple O”) – which uses an existing OpenStack
cloud to bootstrap and manage a new OpenStack cloud. The recent <a href="http://www.meetup.com/Australian-OpenStack-User-Group/events/189477362/">Australian
OpenStack User Group</a> at the Anchor Systems offices in Sydney had
several talks about Triple O.</p>
<h2 id="sydney-postgresql-user-group">Sydney PostgreSQL User Group</h2>
<p>I’ve always quite liked <a href="http://www.postgresql.org/">PostgreSQL</a> but my current project is my first
chance to work with it in a while. The <a href="http://www.meetup.com/Sydney-PostgreSQL-User-Group/events/197696352/">Sydney PostgreSQL User
Group</a> meeting last week had a presentation by Venkata B Nagothi
from Fujitsu Australia about the changes in the forthcoming PostgreSQL 9.4
release.</p>
<h2 id="port80-sydney">Port80 Sydney</h2>
<p>I was a regular attendee at Port80 in Perth for years, but haven’t been to
<a href="http://www.meetup.com/Port80-Sydney/events/192062222/">Post80 Sydney</a> since I moved here 18 months ago. The meeting last
week was hosted at Anchor, so I stuck around after work to eat some pizza and
listen to the talk about user experience design.</p>]]></summary>
</entry>
<entry>
    <title>DjangoConAU 2013</title>
    <link href="https://passingcuriosity.com/2013/pyconau-and-djangoconau/" />
    <id>https://passingcuriosity.com/2013/pyconau-and-djangoconau/</id>
    <published>2013-07-05T00:00:00Z</published>
    <updated>2013-07-05T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>I’m attending <a href="http://www.djangocon.com.au/">DjangoConAU</a> 2013 (I believe this is the inaugural DjangoCon
Australia) today and PyCon Australia tomorrow. If last year is any guide, it’s
going to be a pretty awesome weekend! I’ll try to update this post over the
course of the day. Not real live blogging, more delayed telecast blogging.</p>
<p>Also: these are notes I’m typing during the sessions. They are probably errors
and such. I’ll come back and tidy them up later. Maybe.</p>
<p><a href="http://teespring.com/dcau2013">DjangoCon Australia 2013 t-shirt</a></p>
<h2 id="alex-gaynor-on-the-divided-web-and-the-role-of-frameworks">Alex Gaynor on the Divided Web and the Role of Frameworks</h2>
<p><a href="http://2013.pycon-au.org/programme/miniconfs/djangocon#gaynor">Alex Gaynor on the Divided Web and the Role of Frameworks</a>
(<a href="https://speakerdeck.com/alex/a-divided-web-and-the-role-of-frameworks">slides</a>). First person to have spoken at DjangoCons on three
continents (for a hour or two).</p>
<p>History of the web: the big bang, ENIAC, Apple II, T.B.L. and Mosaic.</p>
<p>Email and FTP are more applications, but the web technologies (HTML, HTTP,
etc.) are, effectively, platforms: they don’t have any specific thing you do
with them, you do what you like.</p>
<ol type="1">
<li><p>Static content. In vim or something.</p></li>
<li><p>Dynamic content.</p></li>
<li><p>DHTML - nothing good came of this.</p></li>
<li><p>Microsoft invented AJAX (with ActiveX controls).</p></li>
<li><p>“Web 2.0” is what we think “web applicaiton” means these days.</p></li>
</ol>
<p>Frameworks are being release (RoR &amp; Django; see the Snakes and Rubies). These
made lots of stuff that was a pain (“database driven applications”) more
convenient.</p>
<p>Most people land on one side or the other, but current practice seems to have
landed on “both”: backend and frontend are both getting more and more complex.</p>
<p>Technologies are living longer: some of this stuff is likely to be the COBOL of
the future.</p>
<p>All these new tools and technologies don’t create new capabilities, they make
existing capabilities more convenient to manage and to use. Rails and Django to
let you do something new.</p>
<p>Django was designed to allow small groups of people to build complex “web
applications” quickly. It still solves the same problem in 2013 as it did in
2005.</p>
<p>In 2009 there were a few more things that were though required: monitoring,
message quues, APIs, workers, search indexing. Django has nothing to say about
any of these (though many of them are addressed by third-party apps and
external packages).</p>
<p>In 2013 you need deployment, configuration management, to think about SOA,
real-time stuff (Websockets, etc.) and the crazy, crazy world of front-end
Javascript.</p>
<p>We’re building more and more platforms for specific use cases.</p>
<p>In spite of all these new frameworks and tools addressing parts of a puzzle,
nothing has really encroached on Django and Rails yet. Either Django will start
addressing some of these cases or it’ll be made obsolete by something better.</p>
<blockquote>
<p>Everything is getting more complex and bigger.</p>
</blockquote>
<p>Deployment has always sucked but Alex has reason to believe that there is a
bright future.</p>
<ul>
<li>Applications in <a href="http://www.docker.io/">Docker</a> containers.</li>
</ul>
<ul>
<li>Servers configured with Chef &amp; <a href="https://wiki.openstack.org/wiki/Heat">Heat</a> (orchestration as a service; part of
OpenStack?) which run your containers.</li>
</ul>
<p>Most full-service cloud platforms include some sort of orchestration tool
(Heat, CloudFormation).</p>
<p>The “divide” of the title comes in a number of axes:</p>
<ul>
<li>small and big teams</li>
<li>contractors and in-house</li>
<li>“sites” and “apps”</li>
</ul>
<p>The increase in complexity seems to be favouring one side of each divide. “The
ink is never dry”.</p>
<h3 id="qa">Q&amp;A</h3>
<p>Where does Django fit in a world which almost forces us to work in (or, at
least, interoperate with JS)?</p>
<blockquote>
<p>DHH’s comment on Rails’ JS helpers: “Yes, JS is horrible.” Google is
trying something interesting with Dart. It’s probably not particularly
feasible to implement Python on top of JS (like the Dart compat).</p>
<p>“Best viewed in Chrome” must never come back.</p>
</blockquote>
<h2 id="jacob-kaplan-moss-on-porting-django-apps-to-python-3">Jacob Kaplan-Moss on Porting Django apps to Python 3</h2>
<blockquote>
<p>Hey y’all</p>
</blockquote>
<p>Django 1.5 supports Python 3, in Django 1.6 it’s considered stable. So let’s
all use it.</p>
<p>First question is: whether we should use Python 3? The answer is yes. Python 3
is Python with “30% fewer warts”. Biggest improvement is that Unicode really
works.</p>
<p>Second question is: can we use Python 3? This is essentially a question of your
application’s dependencies and whether they’ve been ported yet.</p>
<p>Problems:</p>
<ul>
<li><p>First big problem is choice ot DB. If you use Postgres you’re fine. SQLite
works. MySQL has a connector (but there are licensing concerns, so the
foundation can’t recommend it). You should be using Postgres.</p></li>
<li><p>Second big problem is your server/deployment software: modwsgi, uWSGI and
synchronous gunicorn are all fine. gunicorn async is problematic (due to
gevent). You may need to switch deployment and operation strategy.</p></li>
<li><p>South, Celery, Raven (sentry), django-extensions, all work. But not
django-compressor, django-tagging (last update 2009), django-social-auth,
django-debug-toolbar, Haystack. But there are suitable alternatives to these
(django-pipeline, django-auth, <a href="https://pypi.python.org/pypi/django-taggit">django-taggit</a>).</p></li>
</ul>
<p>Every time working with Python 3 Jacob has had to play this game evaluating
apps and libraries for Python 3 support.</p>
<p>Third question is: should I use Python 3? This can be complicated, with the
additional costs of learning the new stuff, re-/evaluating apps and libraries
for Python 3 support. Perhaps the best advice is to use Python 3 if you can and
Python 2 if you must; Python 3 will be improved, get faster, etc. There’s no
future for Python 2 (possibly decades, but still; RedHat have committed to
supporting it for 2030 or something).</p>
<h3 id="how-do-i-use-python-3">How do I use Python 3?</h3>
<p>If you can, support only Python 3. It’s not too hard to add support for Python
2 later if it becomes necessary during the development process.</p>
<p>Python 3 introduced a tool called <code>2to3</code> which converts Python 2 code for
Python 3 (by doing AST transformations and generating a patch). The Python 3
code being generated, makes it very hard to fix bugs and makes community
contribution very hard.</p>
<p>The “single source” approach is much better: write Python 3 code and include
shims to paper over the deficits when run under Python 2. If you have to
support Python 2 you should be using this technique.</p>
<ol start="3" type="1">
<li><p>Supporting both Python 2 and Python 3 <em>requires</em> automated testing. You
can’t hope to maintain it without continuous integration.</p></li>
<li><p>Fix all the unicode handling issues that your test suite identifies. There
will be lots.</p></li>
<li><p>Iterate on test failures.</p></li>
</ol>
<h3 id="case-study-python.org">Case Study: python.org</h3>
<p>Decided to support only Python 3.3+ (if possible). Left single-source open if
it became necessary later.</p>
<p>Dependencies:</p>
<ul>
<li><p>Light CMS requirements. None of the existing CMS packages supported Python 3
yet, decided to build it as the requirements were so simple.</p></li>
<li><p>Quite complex and specific user, permissions and authentication requirements,
so none of the apps would have been applicable anyway.</p></li>
<li><p>Heavy integration with social media services. None of the social login tools
(which they evaluated) had been ported at the time, so they moved on to other
features and bugged the maintainers to port (and it worked).</p></li>
<li><p>Moderate traffic requirements with extreme spikes related to releases, etc.</p></li>
<li><p>Testing: django-discover-runner works fine on Python 3 (and is, essentially,
included in Django 1.6).</p></li>
<li><p>The hardest part of the process was “retraining our unicode three muscles to
do things the Python 3 way”.</p>
<blockquote>
<p>The biggest thing you can do is eliminate the word “string” from your
vocabulary. Bytes are just bytes, text is text.</p>
</blockquote>
<p><code>django.utils.encoding</code> does this.</p></li>
</ul>
<p>It worked and it’ll be launching in about a month (hopefully).</p>
<p>They estimate the project cost about 20% more to develop, mostly in terms of
increased development time. In large part, most of this time is probably just
changing maintenance costs into upfront costs. And the number is probably
smaller now.</p>
<h3 id="case-study-django-sitetree">Case study: django-sitetree</h3>
<p>Django application for managing a hierarchical navigation tree. Ported by Jeff
Triplett in <a href="https://github.com/idlesign/django-sitetree/commit/c7475">a single commit</a>.</p>
<p>Shared source approach with: Python 2.6+, Python 3.3+; Django 1.4+. This is a
reasonable set of minimum requirements.</p>
<p>There aren’t any dependencies. If your app has dependencies, you may need to
port them too!</p>
<p>Using <a href="http://tox.readthedocs.org">Tox</a> to run test suite in multiple environments. You’ll pick up a
bunch of syntax issues with the changes in Python 3.</p>
<p>Django adds the <code>@python_2_unicode_compat</code> decorator to change <code>__unicode__</code>
into <code>__str__</code> if running on Python 2.</p>
<p><a href="http://pythonhosted.org/six/">Six</a> (included in <code>django.utils.six</code>) helps to
paper over some of the differences (metaclasses, type names of byte and text
types, etc.)</p>
<p>There’s a <a href="http://django.me/py3">guide for porting to Python 3</a> with detailed documentation.</p>
<p>Python 3 is ready, the WSGI containers are ported, the databases are ported,
the frameworks are ported. Now it’s up to the community to port the libraries
and applications.</p>
<h3 id="qa-1">Q&amp;A</h3>
<p>Is <code>from future import unicode</code> a good idea?</p>
<blockquote>
<p>Unicode literals aren’t a thing in Python 3, but using stuff from future is probably a good idea.</p>
</blockquote>
<h2 id="greg-turner-on-using-feincms">Greg Turner on using FeinCMS</h2>
<p>Greg is the filling in a core-contributor sandwich.</p>
<p>The web and web-content are becoming more complex: there are more technologies,
more devices, users expect richer experiences. See <a href="http://www.nytimes.com/projects/2012/snow-fall/">NYT Snowfall</a> for an
example. Teams are getting smaller and smaller (economics, etc.) We need to
build content which is future-proof, cross platform, clean and semantic.</p>
<p>These are the problems that <a href="http://www.feincms.org/">FeinCMS</a> attempts to solve. A document (page)
combines a services of lumps of content (content types, not the same thing as
Django content types).</p>
<p>See the [MCA site][].</p>
<p>FeinCMS provides a model and admin to use as a base in your own app. This
allows site admins to combine and embed different types of content in their
documents (instances of your FeinCMS models).</p>
<p>Each model has specific set of content types which are supported. This is kind
of ugly, <a href="http://github.com/ixc/glamkit-feincmstools">FeinCMStools</a> makes it nicer. He’s made a <a href="https://github.com/ixc/feincmstools-demo">demonstration</a>
(see the tags).</p>
<ol type="1">
<li><p>Define the regions in your content type. https://github.com/ixc/feincmstools-demo/blob/master/djangosite/meetups/models.py#L17</p></li>
<li><p>Define content types which can go in your regions. https://github.com/ixc/feincmstools-demo/blob/master/djangosite/meetups/models.py#L23</p></li>
<li><p>There are lots of tables, so make sure you’re careful with migrations, etc.</p></li>
</ol>
<p>Content types don’t have to be content. Example of a content type, which offers
the site admin a choice of layouts which have been designed and built ready for
them to use.</p>
<h3 id="qa-2">Q&amp;A</h3>
<p>How does FeinCMS handle structured content?</p>
<blockquote>
<p>They are just normal Django models, so they can be as structured and semantic as you like.</p>
</blockquote>
<p>FeinCMS uses Django admin which some users dislike. Any tips on making it nicer?</p>
<blockquote>
<p>Not really. But they use <code>django-admintools</code>. Would like to see a
more heterogenous approach to admin, which many other CMS support and
which better maps to user expectations.</p>
</blockquote>
<h2 id="russell-keith-magee-on-secrets-of-the-testing-masters">Russell Keith-Magee on Secrets of the Testing Masters</h2>
<p>CTO of TradesCloud. Hiring soon if you want to move to Perth.</p>
<p>Testing is good and we should all be doing it. As we all know. First
contribution to django was adding app testing. It has lots of support for
testing contrib, but not everything. Introducing two testing tools which are
helpful and good and such.</p>
<h3 id="problem-you-need-test-data">Problem: You need test data</h3>
<p>Django’s testing framework supports fixtures (declared in test case class).
Fixtures are easy to create, but hard to read, hard to update and include no
documentation. Also include a lot of rubbish which isn’t relevant to the test
(1 line out of 18 when testing “admin can X”). You need to <em>know</em> that user 23
is the “staff user with no existing content”.</p>
<p>Solution is <code>factory_boy</code>: an EDSL for creating test objects in your tests,
programmatically.</p>
<p>You create factory classes for your models. Provide place holder values, use
helpers to generate values (sequences for unique email addresses, lazy values
which are calculated late in the process).</p>
<p>Subfactories all you to create child objects. E.g. BlogPost factory has User
sub-factory for the post author. Can still be overridden on specific cases when
tests require. This overriding can traverse joins just like Django model stuff:
<code>PostF(author__firstname='thomas')</code></p>
<p>Lets you access and override various bits of instance data and the creation
process.</p>
<p>Factory-boy also supports: SQLAlchemy and Mogo.</p>
<p>There’s also a django-factory-boy package which includes pre-defined factories
for Django modules.</p>
<h3 id="problem-youre-dependant-on-an-external-service">Problem: You’re dependant on an external service</h3>
<p>Any external services that you use – payment processing, social networks, etc.
– will affect your ability to test. You might also have trouble testing your
failure cases.</p>
<p>Any internal services might be slow, unreliable or difficult to configure.
Things like deliberately slow password hashing, database failure, etc.</p>
<p>You can just ignore this and not test those bits.</p>
<p>You can use <code>mock</code> (Python 3.3 stdlib <code>unittest.mock</code>, installable on Python
2.7+); essentially organised monkeypatching.</p>
<ul>
<li><p>Mock object which provides pre-defined return values.</p></li>
<li><p><code>@patch</code> decorators to inject mock objects into an existing API.</p></li>
</ul>
<p>Mock instances track how they are used, allowing you to assert various
properties about the way your code is used.</p>
<pre><code>obj = SomeObject()
obj.method = Mock(return_value=3)
obj.method.assert_...</code></pre>
<p><code>@patch</code> allows you to use a function (the decorated function) to replace an
existing function.</p>
<p>There are other similar packages, but Russell likes sticking with the standard
library unless really required.</p>
<p>PS: There will be an announcement during Russell’s PyCon talk.</p>
<h2 id="simon-meers-on-django-unstrained">Simon Meers on Django Unstrained</h2>
<p>Simon (DrMeers online) is part of the Django core team, having discovered
Django in 2008. Lots of clients with deadlines.</p>
<p>Django (like all real Open Source projects) is <em>our</em> framework, it’s up to us
to improve it. We probably want to avoid adding more functionality to Django
core, but helping it to evolve to be an [even more] flexible platform for
third-party contribution. Rich third-party eco-system.</p>
<ul>
<li><p><a href="https://github.com/pennersr/django-allauth">django-allauth</a></p></li>
<li><p><a href="https://github.com/brack3t/django-braces">django-braces</a></p></li>
<li><p><code>django-generic</code> containing snippets and patterns which you use over and over
again. Simon’s snippets package is on <a href="http://bitbucket.org/DrMeers">his BitBucket account</a>.</p></li>
</ul>
<ul>
<li><p><a href="https://pypi.python.org/pypi/django-import-export">django-import-export</a> for
CSV, etc.</p></li>
<li><p>Nested inline forms has been discussed in tickets.</p></li>
<li><p>Floppy forms and Crispy forms improve</p></li>
<li><p>Pass through manager just passes things through to the underlying queryset?
This is something I could have used before.</p></li>
</ul>
<p><a href="http://github.com/DrMeers/">Simon’s Github account</a> will contain the slides at
some point.</p>
<h2 id="tom-eastman-on-the-coolest-parts-of-backend-development-with-django">Tom Eastman on the coolest parts of backend development with Django</h2>
<p>Catalyst IT (in Wellington) have a growing Django team. Come talk to Tom if you
might be interested in moving.</p>
<p>Large, reasonably high profile project for the Department of Education.</p>
<ul>
<li>AngularJS, D3, Compass/SASS for frontend.</li>
<li>Django, gunicorn, tastypie, celery and south.</li>
</ul>
<p>Working in a large team means that back end developers can avoid front-end
stuff like browser quirks, etc. The job then has only three parts:</p>
<ul>
<li>Make it <em>correct</em></li>
<li>Make it <em>fast</em></li>
<li>Make it <em>secure</em></li>
</ul>
<h3 id="correct">Correct</h3>
<blockquote>
<p>Code without tests is broken by design.</p>
</blockquote>
<p>And</p>
<blockquote>
<p>The converse of test-driven development is faith-based development.</p>
</blockquote>
<p>Your tests should be run regularly. Using a tool based on things like <code>inotify</code>
allow you to see test results as you work.</p>
<p><em>You must see your tests fail before they pass.</em> Without this, you can’t tell
that your code makes the test pass. Either the code is wrong or the tests are
wrong.</p>
<p><em>Testing errors is more important than testing the happy case.</em> It’s unusual
for people to test error cases (only usually when the errors occur during
development). Write test cases which cover error cases.</p>
<p>Django gives you all the tools you need to test the things you need to test,
and do it properly.</p>
<p>Continous integration and rigours code review are two of the best inventions
ever. Tools like Jenkins and Gerrit make these reasonably easy to setup.</p>
<p>Took three tries to get integration testing to work:</p>
<ol type="1">
<li><p>Using the Selenium recorder. It generated hideous, unmaintainable code and
gave up.</p></li>
<li><p>PhantomJS is headless webkit controlable with JS. It shows promise but was
rather unstable.</p></li>
<li><p>Went back to Selenium having learned how to split tests from page
controllers (see <a href="http://hedleyproctor.com/2012/07/effective-selenium-testing/">Effective Selenium testing</a>). This makes it easy to
maintain tests when pages change, etc.</p></li>
</ol>
<h3 id="fast">Fast</h3>
<p>Varnish and CDNs are all fun, but can be difficult on sites that contain
non-public information, freshness requirements, etc. How do you keep your web
site fast without public caching?</p>
<p>Using etag and last-modified headers in Django. Use auto-updating timestamps in
models; with appropriate indexes in the database, it can be very fast to check
last-modified headers. Takes more DB queries to check freshness, but is almost
always a speedup; an example view takes 800ms to generate the full response vs
50ms to check modification.</p>
<ol type="1">
<li>Check authorisation.</li>
<li>If the etag matches, yay!</li>
<li>With no etag, serve from cache.</li>
<li>Generate (and cache) the page. (Invalidate cache on saves).</li>
</ol>
<h3 id="secure">Secure</h3>
<p>If you, as a web developer, haven’t read the OWASP Top 10 then you are a
liability to every site you work on.</p>
<p>Things that seem innocuous – processing XML from clients – are often unsafe.
Disable functionality that you don’t need: XML, YAML, etc.</p>
<p>If your site requires logins then your site requires SSL. See Firesheep if you
haven’t seen it.</p>
<p>Django forms are for validating import; not just generating HTML forms. Use
them for everything! Query strings, CSV records, etc. Even if you don’t (yet)
have any rules to enforce, create a form so you’ll have somewhere to put it.</p>
<p>Django can’t protect you if you don’t let it. If you bypass the ORM, then it’s
<strong>your</strong> job to handle SQL injection. If you bypass the template language, then
it’s <strong>your</strong> job to validate.</p>
<p>Annoy your pentester so they <em>really</em> want to find your bugs. Current project
has sent 18,000 emails about 500 errors.</p>
<h3 id="qa-3">Q&amp;A</h3>
<p>Adding tests to a codebase without them?</p>
<blockquote>
<p>You need to be able to put your database into a known state for
testing purposes. Doing smoke test (is it all 200 OK?) are quick and
easy. Unit tests can be easy to start.</p>
</blockquote>
<p>What are the most common issues found in code review?</p>
<blockquote>
<p>Silly mistakes. Often, the review comment is “why wasn’t this
tested?” Often it helps share knowledge about better ways, etc.
throughout the whole team, to notice additional cases which need
testing, etc.</p>
<p>If nothing else, it helps to make sure that the whole team knows about
the code base.</p>
</blockquote>
<h2 id="curtis-maloney-on-a-state-of-rest">Curtis Maloney on A state of REST</h2>
<p>Curtis is responsible for:</p>
<ul>
<li>django-nap</li>
<li>django-rated</li>
</ul>
<p>Everyone who doesn’t hangout on irc://freenode.net#django is missing out.</p>
<p>Django doesn’t really have any REST frameworks; the API frameworks we have
are pretty useful and kinda REST-y, though.</p>
<ul>
<li><p>TastyPie</p></li>
<li><p>Django REST Framework</p></li>
<li><p>django-nap tries to make a faster, smaller TastyPie.</p></li>
</ul>
<p>There are a bunch of features for an API frameworks. Let’s look at a few of
them.</p>
<h3 id="auth">Auth</h3>
<p>Authentication – identifying the user – and authorisation – deciding whether
the user can perform the operation.</p>
<p>TastyPie and DRF both include support for a bunch of authentication approaches.
NAP makes/allows you to do it yourself using existing tools.</p>
<p>See the “Fuck OAuth 2 video”.</p>
<p>Both TastyPie and DRF include their own functionality; NAP allows you to
provide a callback.</p>
<h3 id="data-formats">Data Formats</h3>
<p>TastyPie and DRF both support many frameworks.</p>
<p>NAP supports a few, but only one at a time?</p>
<h3 id="serialisation">Serialisation</h3>
<h3 id="shapes">Shapes</h3>
<p>TastyPie lets you define per-field visibility (list vs details)</p>
<p>NAP (and DRF?) you can specify it per-view.</p>
<h3 id="pagination">Pagination</h3>
<p>TP: Custom class, offset and limit</p>
<p>DRF: django native pagination. page and size.</p>
<p>NAT: django native pagination. Page with size or offset with limit.</p>
<p>Pagination has security implications, unlimited page sizes can allow denial of
service.</p>
<h3 id="rate-limiting">Rate limiting</h3>
<p>Both TastyPie and DRF have their own rate limiting implementations.</p>
<p>NAT doesn’t, because it’s a separate concern (in django-rated).</p>
<h3 id="filtering">Filtering</h3>
<p>Django ORM filtering is important, but a whitelist is important (don’t let
people tranverse links).</p>
<h3 id="versioning">Versioning</h3>
<p>TastyPie: ?</p>
<p>DRF: Viewset (collection of views for responding to HTTP verbs for a collection
of resources) with routing.</p>
<p>NAP: collect a bunch of Publishers into a version.</p>
<h3 id="generic-views">Generic Views</h3>
<p>Can be clumsy to reuse TastyPie resources in your own views.</p>
<p>DRF is built on the generic views approach. It’s the first step in the tutorial.</p>
<p>Using HTTP responses which are also exceptions. So you can produce</p>
<h3 id="overview">Overview</h3>
<p>TastyPie is a very quick way to expose a model as an API, but going further
means learning a lot about it’s APIs and internals.</p>
<p>In compiling the talk, started to doubt continuing NAP at all because DRF is
pretty awesome.</p>
<h2 id="core-developer-panel">Core Developer Panel</h2>
<p>Russell, Chris, JKM, Alex &amp; Simon; moderated by Greg.</p>
<h3 id="whats-the-best-and-worst-things-about-it">What’s the best and worst things about it?</h3>
<p>Russell: The fact that it happens at all is pretty wonderful; but there’s so
much more we could/should be doing.</p>
<p>Jacob: Watching people get into Python because of Django; the expectation was
that it’d see a little takeup from newspaper people and a few who already know
Python, seeing half a room say they learned the language because of Django is
amazing. The idea that some people consider themselves Django developers (and
not Python developers) is somewhat disheartening.</p>
<h3 id="are-their-situations-in-which-you-dont-use-django">Are their situations in which you don’t use Django?</h3>
<p>Alex: Doesn’t use Django much at all in his current role.</p>
<p>Chris: Not much, mostly when required.</p>
<h3 id="streamline-vs-bloat">Streamline vs bloat</h3>
<p>Simon: Core should really, really be streamlined. But we need some more clarity
about the one true tagging app, menu app, etc.</p>
<p>Russell: Flask does the apps thing well, by having a registry of packages and
blesses specific implementations. Everyone should be able to know that pipeline
is better than django-compressor.</p>
<p>Jacob: It doesn’t have to be the core team which does this; they’d much rather
support a community effort.</p>
<p>Alex: It’s not going to happen (talked about it at three panels so far); also
risks stagnation, etc. (Audience member says bollocks, repectfully)</p>
<h3 id="django-2.0">Django 2.0</h3>
<p>Jacob: there will never be a massive change destroying backward compatability
as long as I have anything to do with it; 2.0 will just be 1.9++</p>
<p>Chris: deprecation cycles, etc. are good and breaking stuff is bad.</p>
<h3 id="what-would-you-addremove-from-django">What would you add/remove from Django?</h3>
<p>Russell: probably the stuff around apps/settings/startup. Settings have caused
as many problems as it’s made. App labels (vs just module) are pretty awful.
But still being Django would be difficult.</p>
<p>Alex: the admin; there’s been some reskinning but no real challenges to what
django admin should be.</p>
<p>Jacob: Danny Greenfeld is trying Django Admin 2.</p>
<h3 id="the-django-software-foundation">The Django Software Foundation</h3>
<p>Core committers are all invited to be members, but not all choose to be.</p>
<p>Funding comes from a couple of places:</p>
<ul>
<li><p>Profits from DjangoCon US.</p></li>
<li><p>Membership fees from corporate members.</p></li>
</ul>
<p>It’s been very difficult getting companies to join, in part because it’s a
US-based NFP. It’s also difficult to raise money without having something to
spend it on.</p>
<h3 id="kickstarter-campaigns-etc.">Kickstarter campaigns, etc.</h3>
<p>Alex: This is a good thing. Twisted have created a position to someone to
review patches, etc.</p>
<p>Jacob: The Django community navigates the fraught relationship between OSS and
money better than most. The community is pretty good at coming up with cash
where it’s required to make things happen.</p>
<h3 id="what-will-the-replacement-for-django-be">What will the replacement for Django be?</h3>
<p>Alex: <a href="http://werkzeug.pocoo.org/">werkzeug</a>?</p>
<p>Jacob: Have you watched the <a href="http://meteor.com/">Meteor</a> screencast? The RoR
video in 2004 was a “holy shit” moment because “we have this” (hence open
sourcing Django). This is a “holy shit” moment because we have nothing.</p>
<h3 id="what-should-people-sprint-on">What should people sprint on?</h3>
<p>Russell: 1.6 is coming so people should sprint on triage if they can help;
Porting apps to Python 3; think and talk about the big issues.</p>
<p>Jacob: most of the low-hanging fruit have been picked and everything left is
pretty hard. Pick a specific bug that’s addressing you, or work on a
third-party package.</p>
<h2 id="dylan-jay-on-pyramid-django-and-plone">Dylan Jay on Pyramid, Django and Plone</h2>
<p>There’s a Djangocon tradition of asking people from other Python web frameworks
to speak so we can learn from them. This is that talk. Dylan is a core Plone
contributor and has never written a single line of code for Django; first web
app in 1995 with ISAPI.</p>
<p>Big explosion of web frameworks around 2004 of web frameworks, Rails, Django,
etc. These are all descended from the CGI lineage.</p>
<p>Seperate lineage of Zope then ZTK and Plone. Zope is <em>older</em> than almost
everything in the CGI lineage.</p>
<p>Third lineage of static site generates.</p>
<p>In 1996:</p>
<ul>
<li><p>Webservers serve files at paths.</p></li>
<li><p>CGI = run a script</p></li>
<li><p>OO was big</p></li>
<li><p>CGI was shit, so dude wrote Zope based on objects with traversal and method
invocation based on URL paths.</p></li>
</ul>
<p>ZODB</p>
<p>ZTK:</p>
<ul>
<li><p>Turns out OO isn’t really all that good; use adapters (<code>adaptor :: Interface   i, j =&gt; i -&gt; j</code>)</p></li>
<li><p>Traversal turns into a multiadaptor of Contect, Request and method name to a
browser view.</p></li>
</ul>
<p>Plone:</p>
<ul>
<li>300+ core contributors</li>
<li>400+ plugins (supporting current version)</li>
<li>1000+ commits/month</li>
<li>Sprints, a foundation, etc.</li>
</ul>
<p>Plone services like <a href="https://ploud.com/">ploud</a> and
<a href="http://www.pretagov.com.au">pretagov</a>.</p>
<p>Plone is good at ticking the all boxes you see in government tenders (all by
itself).</p>
<p>The most important thing to consider when evaluating CMS platforms is roles:
reviewers, content editors, site administrators, integrators, frontend
developers, backend developers (in kind of increasing order of technical
ability).</p>
<p>Many of these roles will be present in a large content-oriented site. Being
able to separate and serve the needs of these different user groups.</p>
<p>Frameworks tend to have a straight-line effort/customisation trend, CMS tend to
have non-linear relationship. Once you’ve exceded some limit of customisation,
you’re often better off choosing a framework rather than a CMS.</p>
<p>A framework allows you to start with a pretty blank slate whereas a CMS let’s
you build-up from an already-function-filled starting point.</p>
<p>Pyramid is pretty much the opposite of pyramids:</p>
<ul>
<li>Not ancient</li>
<li>Extensible and flexible (not unchanging for centuries)</li>
<li>Small to big (not big to small)</li>
</ul>
<h2 id="lightning-talks">Lightning Talks</h2>
<h3 id="tim-ansell-talking-about-tims-finance">Tim Ansell talking about Tim’s Finance</h3>
<p><a href="https://github.com/mithro/timsfinance/">Tim’s Finance</a> is an interface to do
various financial things.</p>
<h3 id="jacob-haslehurst-on-permission-migrations">Jacob Haslehurst on Permission Migrations</h3>
<p>Writers, editors, administrators, developers have different permissions.</p>
<p>django-permission-migrations is a small package they’ve pulled out of their
code base. Put permissions in the <code>Meta</code> of the model classes, create a
permissions app for your project and add/remove permissions in the migrations,
define groups in settings, then add migrations which control the permissions.</p>
<h3 id="chris-on-navigation-menus">Chris on Navigation Menus</h3>
<p>Lot’s of Django navigation menus have classes and models and database stuff.
Chris has a simple template tag for doing doing navigation menus. Basically a
helper to write code like:</p>
<pre><code>{% if current == 'apple' %} class=&quot;active&quot; {% endif %}</code></pre>
<p>http://djangosnippets.org/snippets/1729</p>
<h3 id="pandas-loves-ponies">PANDAS loves Ponies</h3>
<p>PANDAS is an R-like stats/data processing package for Python.</p>
<p>pandas-loves-ponies is a library which helps to interface Django with PANDAS
(carry model field names into data frames and similar things).</p>
<h3 id="humphrey-on-form-rendering">Humphrey on form rendering</h3>
<p>Rendering forms isn’t very DRY. Simple app with a template filter to render a
form with a specific tempate.</p>
<p>https://github.com/humphrey/django_formrenderer</p>
<h3 id="danielle-madeley-on-crisper-keeps-crispy-forms-crisper-longer">Danielle Madeley on Crisper keeps Crispy Forms crisper longer</h3>
<p>Currently working on a form heavy app. <a href="http://django-crispy-forms.readthedocs.org/en/latest/">django-crispy-forms</a> is a
django app to make forms a little DRYer. Crisper is an additional - related -
template tag to help detect potential problems with forms, etc. Looks pretty
cool.</p>
<h2 id="thanks">Thanks</h2>
<p>Thanks to all the speakers, sponsors, organisers, volunteers, AV team (the
videos will be at <a href="http://pyvideo.org">pyvideo.org</a> at some point).</p>]]></summary>
</entry>
<entry>
    <title>Planning for DrupalDownunder</title>
    <link href="https://passingcuriosity.com/2011/planning-for-drupaldownunder/" />
    <id>https://passingcuriosity.com/2011/planning-for-drupaldownunder/</id>
    <published>2011-01-12T00:00:00Z</published>
    <updated>2011-01-12T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>While Brisbane and Queensland are in the grip of some fairly serious flooding
(please consider donating to the <a href="http://www.qld.gov.au/floods/donate.html">Queensland state government relief
fund</a>) the official word is that
<a href="http://drupaldownunder.org/flood-update">DrupalDownunder will be going ahead</a> so I’ve been going through
the programme and narrowing down the sessions I want to see. There are a few
bits and pieces I’m not sure of, but my weekend is going to look something
like this:</p>
<p>On Saturday there’re two keynote sessions and five slots with competing
sessions.</p>
<ol type="1">
<li><p>The <a href="http://drupaldownunder.org/session/exportables">Exportables</a> session
by <a href="http://drupal.org/user/35266">Simon Hobbs</a> will no doubt help in my quest to develop a
reliable and efficient workflow at work.</p></li>
<li><p><a href="http://drupal.org/user/15091">Allie Micka</a>’s keynote <a href="http://drupaldownunder.org/session/allie-mickas-keynote">Running a Drupal business and
contributing to Drupal
sustainably</a> is a
keynote and sounds interesting enough, if not quite my cup of tea.</p></li>
<li><p><a href="http://drupal.org/user/116305">Dave Hall</a>’s <a href="http://drupaldownunder.org/session/building-distributions-drupal-7">Building Distributions with Drupal
7</a> will,
again, help in my quest for standardisation and automation to simplify
workflows.</p></li>
<li><p><a href="http://drupal.org/user/188162">Josh Waihi</a>’s keynote <a href="http://drupaldownunder.org/session/keynote-goodbye-centralization-hello-distribution-introduction-git">Goodbye Centralization, Hello
Distribution: An Introduction to
Git</a>,
is an introduction to git (which I already use and am relatively familiar
with).</p></li>
<li><p>Given the number of times I’ve been asked about options for paid
membership, the <a href="http://drupaldownunder.org/session/paid-membership-sites">Paid Membership
Sites</a> session by
<a href="http://drupal.org/user/279264">Chris Hood</a> will scratch an itch of mine (which other people have
been tickling).</p></li>
<li><p>As I’ve implemented two or three custom CCK fields (and others on my team
have implemented another few), <a href="http://drupal.org/user/86970">Ivan Zugec</a>’s session on <a href="http://drupaldownunder.org/session/fields-core-how-create-custom-field">Fields
in Core: How to create a custom
field</a>
is sure to be interesting.</p></li>
<li><p><a href="http://drupal.org/user/1">Dries</a>’ keynote session with <a href="http://drupaldownunder.org/session/dries-keynote">details to
come</a> is by Dries. And a
keynote. And by Dries.</p></li>
</ol>
<p>My choices on Sunday are less clear cut in spite of having a choice in only
four slots:</p>
<ol type="1">
<li><p>I expect <a href="http://drupal.org/user/446626">John Zornig</a> session about <a href="http://drupaldownunder.org/session/building-document-management-system-drupal">Building a document
management system in
Drupal</a>
to be inspiring when combined with my recent interest in Solr-based search.</p></li>
<li><p>Both <a href="http://drupaldownunder.org/session/turbo-charge-your-drupal-site">Turbo charge your Drupal
site</a> by
<a href="http://drupal.org/user/370574">Kim Pepper</a> and <a href="http://drupaldownunder.org/session/fancy-pants-wysiwyg-editing">Fancy Pants WYSIWYG
Editing</a> by
<a href="http://twitter.com/boztek">Boris Gordon</a> sound interesting and useful.</p></li>
<li><p><a href="http://drupaldownunder.org/session/session-dries">Session by Dries</a>.</p></li>
<li><p>I’ve got a bunch of projects coming up at work that need payment solutions
of various types so <a href="http://drupaldownunder.org/session/session-allie-micka">The Payment api and its framework approach to module
development</a> by <a href="http://drupal.org/user/15091">Allie
Micka</a> will obviously be useful, but I’m personally interested in
systems administration and performance so <a href="http://drupaldownunder.org/session/horizontally-scaling-drupal">Horizontally Scaling
Drupal</a> by
<a href="http://drupal.org/user/116305">Dave Hall</a> sounds interesting. <a href="http://drupaldownunder.org/session/simple-page-layouts-and-customisations-using-views-cck-and-css">Simple page layouts and
customisations using Views, CCK and
CSS</a>
by <a href="http://drupal.org/user/1042818">Dale Baldwin</a> sounds a bit entry level.</p></li>
<li><p>Both <a href="http://drupaldownunder.org/session/case-studies-nswgov-and-abc">Case-Study: ABC Dig
Music</a> by
<a href="http://drupal.org/user/254857">David Peterson</a> and <a href="http://drupaldownunder.org/session/migrating-drupal-web-environment">Migrating to a Drupal Web
Environment</a>
by <a href="http://drupal.org/user/895162">Fiona Bush</a> sound like they’ll have interesting insights. I’ll
probably go Fiona’s session, if only because I went to ANU for a while.</p></li>
<li><p><a href="http://twitter.com/outlandishjosh">Josh Koenig</a>’s keynote session <a href="http://drupaldownunder.org/session/josh-koenigs-keynote">details to
come</a>.</p></li>
<li><p><a href="http://drupaldownunder.org/session/lightning-talks">Lightning talks</a> are
alway good (or, at least, over quickly).</p></li>
</ol>
<p>Now that I’ve thought about it these plans will be making their way into my
calendar.</p>]]></summary>
</entry>
<entry>
    <title>IE performance problem turns out to be images not found</title>
    <link href="https://passingcuriosity.com/2010/ie-performance-problem/" />
    <id>https://passingcuriosity.com/2010/ie-performance-problem/</id>
    <published>2010-11-10T00:00:00Z</published>
    <updated>2010-11-10T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Like many people including, I suspect, most of the web industry I avoid
Internet Explorer as much as I can and my cross browser (i.e. IE) testing can
be somewhat curtailed: I do it with the site in my development environment and
with an eye to degrading gracefully – if you’re using 10 year old software,
you can take the degraded experience and be happy you get that much.</p>
<p>Today I had to look at a client’s web-site to resolve a performance problem
that I’d heard of a few times but had never been able to reproduce. The
reports looked something like this:</p>
<blockquote>
<p>Can you look take a look at our site again? It’s very slow to load
the page but all the other sites I try are fast. It works find on
[manager’s] Mac but my PC and the rest are all slow.</p>
</blockquote>
<p>First things first, I fired up a Windows install in <a href="http://virtualbox.org/">Virtual Box</a> and
found that, yes, it was indeed slow on IE (but not on any other browser I
tried).</p>
<p>Given that there’s a bit of fancy schmancy JavaScript going that was my next
port of call. After a while trying to find the option to disable JavaScript
(Internet Explorer has one of the worst configuration interfaces of pretty
much any software I’ve used) I remembered that this install had the developer
toolbar installed. A quick navigate through three or four layers of menu
(Seriously Microsoft: try giving some consideration to user experience one
day. You might find you like it!) and a visit to <em>Disable -&gt; Scripts</em> and I’d
confirmed that yes, the problem was only seen with scripting enabled.</p>
<p>There are various bits of <a href="http://jquery.com/">jQuery</a> used on the site including a light-box
popup thing, a slideshow type arrangement and a few custom bits. I cloned the
site into my development environment and prepared to set to with my trusty
<code>/* */</code>. Horror of horrors, the problem went away. A few goes back and forth
over <code>hosts</code> and it was clear – the problem happened “live” (with JavaScript)
but didn’t happen at all locally. Crap.</p>
<p>As a last resort before breaking a live site to try to diagnose the issue I
<a href="http://twitter.com/thsutton/status/2242895809617920">appealed to Twitter</a>. A few responses from some helpful sorts didn’t
point out any obvious things to check (and pretty much discounted my own
theory of blaming: my favourite of Microsoft’s misfeatures, filters). In a
last ditch effort to find the problem without disabling bits of the live site
I <a href="http://twitter.com/thsutton/status/2253564831338496">appealed again to Twitter</a> for someone to jog my memory. I remembered a
site that I’d seen before (in mid-October, it turns out) that provided
performance data <em>and</em> screenshots from real browsers. <a href="http://twitter.com/nickobec/status/2256181678571520">Nick Cowie</a>
replied with the linked that saved me hours: I was looking for
<a href="http://www.webpagetest.org/">webpagetest.org</a>!</p>
<p><em>WebPagetest</em> is a free web-page performance service. Give it a URL (and maybe
set some options), wait a little while, and you get back report about your
site. Like most such things you get a screen shot, but more usefully
<em>WebPagetest</em> provides a timeline of fetching and rendering the page. Here’s
an edited screenshot of that first report:</p>
<figure>
<img src="/files/2010/11/ie-performance-start.png" alt="A clear performance problem!" />
<figcaption aria-hidden="true">A clear performance problem!</figcaption>
</figure>
<p>Notice, if you will, all that red and yellow and the fact that the initial
request took 53 seconds and subsequent requests took 31 seconds! A closer look
at the waterfall chart shows that around a third of the time to load and
render the page comes from those red requests – about a dozen requests that
result in 404s – so I set about fixing them. It was evident that they were
images that form the border of the <a href="http://fancybox.net/">Fancybox</a> “popup” and a quick <code>grep</code>
saw that they were referenced from <code>fancybox.css</code> with a relative path. I was
wrong when I though that filters weren’t to blame: <a href="http://reference.sitepoint.com/css/filter">Microsoft’s
<code>filter</code></a> hack interprets paths to images relative to the document
being displayed not the stylesheet it is defined in (unlike every other
reference to an external resource in a stylesheet). One such error might not
be a problem: a silly, preventable mistake, but not critical (beyond the
resource not being loaded and used). A dozen means that IE stalls for
<code>12 URLs / 2 connections * load time</code> which can be ages if your slowish CMS
is serving the 404 pages.</p>
<p>I fixed the missing files (by duplicating them to the expected location, I’m
afraid) and the load time dropped by some 20 seconds. Job done.</p>
<p>All that yellow looked a bit dodgy though, so I kept going. Most of that is
indicating requests that could have been cached on the client but weren’t
because of configuration issues. I added some <a href="http://httpd.apache.org/docs/2.2/mod/mod_expires.html"><code>ExpiresDefault</code></a> server
directives and pretty much all that yellow went away:</p>
<figure>
<img src="/files/2010/11/ie-performance-finish.png" alt="A much faster site!" />
<figcaption aria-hidden="true">A much faster site!</figcaption>
</figure>
<p>Resolving a few 404 errors that slipped through the obviously gaping cracks in
our QA procedure and correcting some server configuration oversights took this
site from load and render times of 53 seconds and 31 seconds (initial and
subsequent, respectively) down to 23 seconds and 2.6 seconds!</p>
<p>There are three things that have come out of this experience:</p>
<ol type="1">
<li><p>The client’s problem has finally been resolved.</p></li>
<li><p>It’s pretty clear that I’ve got a lot of work to do improving our quality
assurance procedures.</p></li>
<li><p>It’s also clear that developing a server configuration with reasonable
defaults will result in some dramatic performance improvements.</p></li>
</ol>
<p>Now it’s time to fill these gaps so that we catch this type of issue and pick
these low-hanging fruit in our current and future work.</p>]]></summary>
</entry>
<entry>
    <title>Progress with Jekyll</title>
    <link href="https://passingcuriosity.com/2010/progress-with-jekyll/" />
    <id>https://passingcuriosity.com/2010/progress-with-jekyll/</id>
    <published>2010-01-13T00:00:00Z</published>
    <updated>2010-01-13T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>I started this new incarnation of Passing Curiosity with stock
<a href="https://github.com/mojombo/jekyll">Jekyll</a>, the content <a href="http://wiki.github.com/mojombo/jekyll/blog-migrations">imported</a> imported from my old
Wordpress blog, and <a href="http://mark.reid.name/">Mark Reid</a>’s excellent Creative Commons
licenced <a href="http://github.com/mreid/mark.reid.name/">design</a>.</p>
<p>I pared it back from Mark’s more complex use case and reworked the templates
and stylesheets a bit to make them more HTML5-y, but there’s still a way to
go. Eventually, I’d like to use the new <a href="http://diveintohtml5.org/semantics.html">semantic tags</a> throughout and
make the design my own.</p>
<p>I tweaked the 404 page to (naïvely) extract the words from bad URLs and
pre-fill the Google search box. Still on the search engines theme I also added
an <a href="http://sitemaps.org/">XML Sitemap</a> template – which lists the index, archive, and every
post – and a <code>robots.txt</code> which references it.</p>
<p>Following <a href="http://benjaminthomas.org/">Benjamin Thomas</a>’ <a href="http://benjaminthomas.org/2009-10-21/custom-liquid-tags-in-jekyll.html">guide</a> I now use a custom <code>jekyll</code>
command which loads extension code when processing the site (without having to
fork Jekyll itself). At the moment, this is just loading <a href="http://metajack.im/">Jack Moffitt</a>’s
<a href="http://github.com/metajack/jekyll/blob/master/lib/jekyll/filters.rb"><code>html_truncatewords</code></a> filter.</p>
<p>The new filter is used in the index, archives, and Atom feed templates and the
<code>&lt;meta&gt;</code> tags to generate a description when a post does not have an excerpt.
I plan on extending the set of meta-data included in each page to include as
much of the <a href="http://dublincore.org/">Dublin Core</a> <a href="http://dublincore.org/documents/dces/">Element Set</a> as makes sense. Some of it
will come from the site and post YAML data, but others will need custom Liquid
tags to determine the correct values automatically.</p>
<p>In all, it’s been a busy couple of evenings but Jekyll is refreshingly simply
and delightfully easy to start hacking with.</p>]]></summary>
</entry>
<entry>
    <title>Edge of the Web 2009</title>
    <link href="https://passingcuriosity.com/2009/edge-of-the-web-2009/" />
    <id>https://passingcuriosity.com/2009/edge-of-the-web-2009/</id>
    <published>2009-11-02T00:00:00Z</published>
    <updated>2009-11-02T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>I’m looking forward to attending <a href="http://www.edgeoftheweb.org.au/">Edge of the Web 2009</a>. <a href="http://www.edgeoftheweb.org.au/program/">The
programme</a> looks pretty
interesting, though some of the abstracts are a teensy bit vague.</p>
<p>I’m currently planning to attend the keynote presentations:</p>
<ul>
<li><a href="http://www.edgeoftheweb.org.au/program/anil-dash/">Anil Dash – Next Year’s Web</a></li>
<li><a href="http://www.edgeoftheweb.org.au/program/alex-payne/">Alex Payne – The Importance of Language: How The Technologies We
Use Shape the Web</a>; and</li>
<li><a href="http://www.edgeoftheweb.org.au/program/derek-powazek-wisdom-of-community/">Derek Powazek – Wisdom of Community</a>. And the panel thingo.</li>
</ul>
<p>And I’ve decided on the following sessions:</p>
<ul>
<li><a href="http://www.edgeoftheweb.org.au/program/lachlan-hardy-building-better-cheaper-sites-on-the-open-web/">Lachlan Hardy – Building Better, Cheaper Sites on the Open Web</a></li>
<li><a href="http://www.edgeoftheweb.org.au/program/dmitry-baranovskiy-writing-better-javascript-libraries/">Dmitry Baranovskiy – Writing Better JavaScript Libraries</a></li>
<li><a href="http://www.edgeoftheweb.org.au/program/kevin-yank/">Kevin Yank – CSS Frameworks: Make the Right Choice</a></li>
<li><a href="http://www.edgeoftheweb.org.au/program/darcy-laycock-matt-didcoe/">Darcy Laycock &amp; Matt Didcoe – Making your website aware/geoaware</a></li>
<li><a href="http://www.edgeoftheweb.org.au/program/justin-mclean/">Justin Mclean – A practical guide to connecting hardware to the web</a></li>
</ul>
<p>That leaves only the Wednesday afternoon session to decided. I’m not much for lawyers or the law, so I’m going to have to choose between:</p>
<ul>
<li><a href="http://www.edgeoftheweb.org.au/program/nick-cowie-progressive-enhancement-with-css-or-how-i-stopped-worrying-about-ie6-and-started-loving-css3/">Nick Cowie – Progressive Enhancement with CSS: Or how I stopped worrying about IE6 and started loving CSS3</a>; and</li>
<li><a href="http://www.edgeoftheweb.org.au/program/myles-eftos-stuff-they-never-taught-you-at-website-school/">Myles Eftos – Stuff They Never Taught You at Website School</a>.</li>
</ul>
<p>On Friday I’m going to two of the <a href="http://www.edgeoftheweb.org.au/workshops/">workshops</a>:</p>
<ul>
<li>Twitter Platform In-Depth – Alex Payne; and</li>
<li>JavaScript: beyond the DOM and AJAX – Dmitry Baranovskiy.</li>
</ul>
<p>In addition to the conference, I’m going to a few of the <a href="http://www.edgeoftheweb.org.au/fringe-events/">fringe
events</a>:</p>
<ul>
<li>the <a href="http://forums.port80.asn.au/showthread.php?t=13483">inaugural UX Bookclub</a></li>
<li>the <a href="http://www.port80.asn.au/">Perth Port80</a></li>
<li><a href="http://webjam.com.au/webjam11">Webjam 11</a></li>
</ul>
<p>A busy week.</p>]]></summary>
</entry>
<entry>
    <title>Haskell FastCGI with Apache</title>
    <link href="https://passingcuriosity.com/2009/haskell-fastcgi-with-apache/" />
    <id>https://passingcuriosity.com/2009/haskell-fastcgi-with-apache/</id>
    <published>2009-06-25T00:00:00Z</published>
    <updated>2009-06-25T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>It’s pretty easy to get started with Haskell web-applications using the
<a href="http://hackage.haskell.org/package/cgi">cgi</a> and <a href="http://hackage.haskell.org/package/fastcgi">fastcgi</a> packages, but a little bit of extra
documentation never hurt anything. What follows is a brief run-down of getting
a Haskell FastCGI program compiled and working under Apache with
<code>mod_fastcgi</code>.</p>
<h3 id="installing-the-software">Installing the software</h3>
<p>There are two important pieces of software to install before we can build our
application: Apache with <code>mod_fastcgi</code>, and the Haskell FastCGI library. You
should install Apache as you normally do. This probably involves one of the
following commands:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>    <span class="fu">sudo</span> pacman <span class="at">-S</span> apache <span class="co"># On Arch Linux</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">sudo</span> aptitude install apache2 <span class="co"># On Debian, Ubuntu, etc.</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">sudo</span> port install apache2 <span class="co"># On Mac OS X with Macports</span></span></code></pre></div>
<h4 id="installing-the-fastcgi-module">Installing the FastCGI module</h4>
<p>Next, you will need to install <code>mod_fastcgi</code>. This may be packaged for your
system, in which case you can use <code>pacman</code>, <code>aptitude</code>, <code>port</code>, etc. as
appropriate. If it is not, you’ll need to build it. Happily, this is dead
easy:</p>
<p>Download and unpack the <code>mod_fastcgi</code> source from
<a href="http://www.fastcgi.com/dist/">http://www.fastcgi.com/dist/</a>. Edit <code>Makefile.AP2</code> to point to your
Apache root (the directory which contains <code>build/</code>). In my case (on Arch
Linux), this was <code>/usr/lib/httpd/</code>. Compile and install it with <code>make -f Makefile.AP2 &amp;&amp; make -f Makefile.AP2 install</code>.</p>
<p>Next, you’ll need to enable the module. The “correct” way to do this varies
wildly from distribution to distribution. In particular, Debian-based systems
like to spread this out over some three or four files.</p>
<p>Edit your Apache configuration (mine was in <code>/etc/httpd/conf/httpd.conf</code>) to
load the module:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>    LoadModule<span class="st"> fastcgi_module modules/mod_fastcgi.so</span></span></code></pre></div>
<p>There are a number of ways to configure the module, but the easiest is to add
it as a handler for <code>.fcgi</code> files. Add the following snippet to <code>httpd.conf</code>:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>    <span class="fu">&lt;IfModule</span><span class="at"> fastcgi_module</span><span class="fu">&gt;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>        AddHandle fastcgi-script<span class="st"> .fcgi</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">&lt;/IfModule&gt;</span></span></code></pre></div>
<p>You’ll still need to add the <code>ExecCGI</code> option to the directories which contain
the <code>.fcgi</code> files to be run. I’m planning to use my <code>~/public_html/</code>
directory, so I amended the <code>&lt;Directory&gt;</code> section in
<code>/etc/httpd/conf/extras/httpd-userdir.conf</code>:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode apache"><code class="sourceCode apache"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>    <span class="ex">Options</span><span class="ch"> </span><span class="kw">+ExecCGI</span></span></code></pre></div>
<p>Restart Apache and you’re good to go. If anything goes wrong, try looking at
the <a href="http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html"><code>mod_fastcgi</code> documentation</a>.</p>
<h4 id="installing-the-haskell-libraries">Installing the Haskell libraries</h4>
<p>Installing the Haskell libraries should be a little more straightforward: just
use <a href="http://haskell.org/cabal/">Cabal</a>.</p>
<ol type="1">
<li><code>cabal update</code></li>
<li><code>cabal install --global cgi</code></li>
<li><code>cabal install --global fastcgi</code></li>
</ol>
<p>If your <code>cabal</code> does not know how to become root, you may need to prefix those
<code>cabal install</code> commands with <code>sudo</code> (or, better yet, edit <code>~/.cabal/config</code>
to specify <code>root-cmd: sudo</code>).</p>
<p>Your environment is now ready to build and run FastCGI applications in
Haskell.</p>
<h3 id="building-a-test-application">Building a test application</h3>
<p>A simple Haskell FastCGI application looks like this (largely cribbed from
<a href="http://mult.ifario.us/p/wiring-haskell-into-a-fastcgi-web-server">Paul Brown’s blog</a>):</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>    <span class="kw">module</span> <span class="dt">Main</span> ( main ) <span class="kw">where</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">import</span> <span class="dt">Control.Concurrent</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">import</span> <span class="dt">Network.FastCGI</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="ot">    action ::</span> <span class="dt">CGI</span> <span class="dt">CGIResult</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>    action <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>        setHeader <span class="st">&quot;Content-type&quot;</span> <span class="st">&quot;text/plain&quot;</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>        tid <span class="ot">&lt;-</span> liftIO myThreadId</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>        output <span class="op">$</span> <span class="fu">unlines</span> </span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>            [ <span class="st">&quot;I am a FastCGI process!&quot;</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>            , <span class="st">&quot;Hear me roar!&quot;</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>            , <span class="st">&quot;&quot;</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>            , <span class="fu">show</span> tid</span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>            ]</span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a><span class="ot">    main ::</span> <span class="dt">IO</span> ()</span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a>    main <span class="ot">=</span> runFastCGIConcurrent' forkIO <span class="dv">10</span> action</span></code></pre></div>
<p>Copy and paste that code into a file (I’ll call it <code>Main.hs</code>) and compile it:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>    <span class="ex">ghc</span> <span class="at">-threaded</span> <span class="at">--make</span> <span class="at">-o</span> ~/test.fcgi Main.hs</span></code></pre></div>
<p>You’ll now have a file <code>~/public_html/test.fcgi</code> which you can call using
<code>curl</code>. The first request might be a little slow, but subsequent requests
should be much faster:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>    <span class="ex">curl</span> <span class="at">--include</span> http://localhost/~<span class="va">$USER</span>/test.fcgi</span></code></pre></div>
<p>Congratulations! You now have a working Haskell FastCGI application hosted
under Apache. If you have any suggestions, comments, or questions, please
leave a comment.</p>]]></summary>
</entry>
<entry>
    <title>Django form fields and templates</title>
    <link href="https://passingcuriosity.com/2009/django-form-fields-and-templates/" />
    <id>https://passingcuriosity.com/2009/django-form-fields-and-templates/</id>
    <published>2009-06-22T00:00:00Z</published>
    <updated>2009-06-22T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>I’ve been working with <a href="http://djangoproject.org/">Django</a> for the last little while (or long
while) and something that stumped me for a while was a useful, generic
approach to marking-up forms in HTML. In particular, making it possible to use
CSS to style classes of fields (all checkboxes, for instance, or all
date-pickers) effectively. Doing so requires being able to write a selector to
pick such elements out, but I found it very difficult to do so.</p>
<p>The only way, as far as I (and <a href="http://groups.google.com/group/django-users/browse_thread/thread/16493dd43303efd3">the replies on django-users@</a>), is to write a template filter to extract a such a value for you. Thankfully, this it pretty easy:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>    <span class="at">@register.filter</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> field_type(field):</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>        <span class="co">&quot;&quot;&quot;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="co">        Get the name of the field class.</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="co">        &quot;&quot;&quot;</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="bu">hasattr</span>(field, <span class="st">'field'</span>):</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>            field <span class="op">=</span> field.field</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>        s <span class="op">=</span> <span class="bu">str</span>(<span class="bu">type</span>(field.widget).<span class="va">__name__</span>)</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>        s <span class="op">=</span> s.rpartition(<span class="st">'Input'</span>)[<span class="dv">0</span>]</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>        s <span class="op">=</span> s.lower()</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> s</span></code></pre></div>
<p>I can use the above filter to add a class to my form markup:</p>
<pre class="django"><code>            &lt;div class=&quot;form-field form-{{ field|field_type }}&quot;&gt;
                {{ field.label_tag}}
                {{ field.errors }}
                {{ field }}
            &lt;/div&gt;</code></pre>
<p>Which I can then use in my CSS to style particular widgets without having to do them one-by-one using ID’s:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode css"><code class="sourceCode css"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">.form-field</span> label {</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">display</span><span class="ch">:</span> <span class="dv">block</span><span class="op">;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">width</span><span class="ch">:</span> <span class="dv">15</span><span class="dt">%</span><span class="op">;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">float</span><span class="ch">:</span> <span class="dv">left</span><span class="op">;</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>div<span class="fu">.form-checkbox</span> label {</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">width</span><span class="ch">:</span> <span class="dv">85</span><span class="dt">%</span><span class="op">;</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">float</span><span class="ch">:</span> <span class="dv">right</span><span class="op">;</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">clear</span><span class="ch">:</span> <span class="dv">right</span><span class="op">;</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>div<span class="fu">.form-checkbox</span> input {</span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">float</span><span class="ch">:</span> <span class="dv">left</span><span class="op">;</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">margin-left</span><span class="ch">:</span> <span class="dv">12</span><span class="dt">%</span><span class="op">;</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>]]></summary>
</entry>

</feed>
