Commits

Sebastián Magrí committed dcc788e Merge

Merge changes from stephenmcd/default

Comments (0)

Files changed (249)

 docs/build/
 dist/
 mezzanine/project_template/static/
+/mezzanine/.project
+/mezzanine/.pydevproject
 build
 dist
 *.egg-info
+*.egg
 project_template/static
 
 40d15e9fcbe6edd6fda67e66e8c0a77dc3e981eb 1.4.3
 2f6220d75320f84ec625eb8c2bf58ed27ed42e3b 1.4.4
 d71ab836ca8de76fc5e64abd4ec680a20205fc49 1.4.5
+94f1427035e19cdd0c88cc2b0255ec6bbe0265ce 1.4.6
+473f680211b61fb95712393b230bd08f0c2e2597 1.4.7
+6c7b600d24f82e637f8f5f41a5e9ce63c4c52470 1.4.8
+8f36e641249ecccfa7a30f3ca80dcb291b047c25 1.4.9
+f5df33a803b0faac7ac5d472faa624bbafe394e8 1.4.10
+7fcbd3bc6dc95a9538904362a37998374bdd8bfe 1.4.11
+f8b79a83b3efd99c791c3332e94e872c60f53066 1.4.12
+90aff0815bf0f84991331d1b6b035179f0b38379 1.4.13
+e83ad5bdfedc42e07c9a7b210174957ede38ddeb 1.4.14
+a2498581497015c265ed16abd79aa06fe326959d 1.4.15
+29f28b33f710e72635b4b1a8c7304518130219fa 1.4.16
 language: python
 env:
-  - DJANGO_VERSION=1.4
-  - DJANGO_VERSION=1.5
+  - DJANGO_VERSION=1.4.8
+  - DJANGO_VERSION=1.5.4
 python:
   - "2.6"
   - "2.7"
 install:
   - pip install django==$DJANGO_VERSION --use-mirrors
   - pip install . --use-mirrors
-  - pip install pep8 pyflakes --use-mirrors
-before_script:
-  - "cp mezzanine/project_template/local_settings.py.template mezzanine/project_template/local_settings.py"
 script:
-  - ./mezzanine/project_template/manage.py test
+  - python setup.py test
 notifications:
   irc: "irc.freenode.org#mezzanine"
   on_success: change
 * Sachin Shende
 * Sam Kingston
 * José Aliste
+* Marcos Scriven
+* Gabe Smedresman
+* Kim Tore Jensen
+* Mike Wakerly
+* Jeff Fein-Worton
+* Petr Papoušek
+* Andrey Zhukov
+* Alexandre Hajjar
+* Breno Uchoa
+* Nar Kumar
+* Tim Slot
+* Andromeda Yelton
+* John Groszko
+* Jeremie Ferry
+* Eduardo S. Klein
+* Jason Wong
+* Romain Hardouin
+* Ling Thio
+* Tim Valenta
+* Artem Gluvchynsky
+* Dheeraj Sayala
+* Antoine Catton
+* Marek Wywiał
+* Vinod Kurup
+* Ethan Goldstine
+* Henri Koivuneva
+* Mehmet Özgür Bayhan
+* Thomas Rega
+* Deric Crago
+* Cristian Ciupitu
+* Danny Sag
+* Troy Harvey
+* Ahmet Bakan
+* Ben Ledbury
+* Nicole Harris
+* David Winterbottom
+* David Higgins
+* hanchen
+* John Henry
+* Cornel K
+* Tuk Bredsdorff
+* Simon Griffee
+* Markus Törnqvist
+* Alyssa Welles
+* Tulio Nobrega
+* Ed Schofield
+Version 1.4.16 (Sep 30, 2013)
+-----------------------------
+
+  * Revert broken static proxy change - Stephen McDonald
+  * Better fix for static proxy urls - Stephen McDonald
+
+Version 1.4.15 (Sep 29, 2013)
+-----------------------------
+
+  * Blog: Generate RSS and Atom feeds through ``richtext_filters`` - Eduardo Rivas
+  * Strip ``STATIC_URL``, leading / from proxied URLs. ``STATIC_URL`` often contains host or ``generic_host`` (esp. if ``STATIC_URL`` is a. path on the same domain), so it needs to be removed first to ensure it. is removed completely. Also removed leading '/' from URL, since it. appears staticfiles doesn't like absolute paths - Adam Brenecki
+  * Added a function ``mezzanine.utils.urls.next_url`` which is used to retrieve redirect URLs from a request's next param, while verifying that the redirect URL is valid - Stephen McDonald
+  * Fix min Dajngo version - Stephen McDonald
+  * Use ``request.get_host`` rather than ``request.META['HTTP_HOST']`` - Stephen McDonald
+  * Fix Django version for travis - Stephen McDonald
+
+Version 1.4.14 (Sep 14, 2013)
+-----------------------------
+
+  * Blog: Catch exception if a non-existent month is requested from the archives - Eduardo Rivas
+
+Version 1.4.13 (Sep 11, 2013)
+-----------------------------
+
+  * 1.fix comments errors - hanchen
+  * Allow for there being no "errors" in the twitter api response. When a successful "user" query to the twitter api is completed the json that is returned is a list. In order to validate the response the code tests to see if it was a dictionary with an "error" key. However passing a string as a index to a list will raise a TypeError, which was not being caught by the "except" clause. I have added TypeError to the list of items being caught. There are of course other ways of verifying the response but I think just adding the TypeError is in keeping with what you have already done. For reference, here is what I was seeing: > python ``manage.py`` ``poll_twitter`` --traceback --force. Traceback (most recent call last): ,. File ``"/,/lib/python2.7/site-packages/mezzanine/twitter/models.py"``, line 74, in run. raise TwitterQueryException(tweets["errors"][0]["message"]). TypeError: list indices must be integers, not str - David Higgins
+  * Fix tag cloud factor in generic app - Stephen McDonald
+
+Version 1.4.12 (Aug 27, 2013)
+-----------------------------
+
+  * Remove bad 1.6 handling - Stephen McDonald
+  * Fix settings context processor for email template contexts when cache installed - Stephen McDonald
+
+Version 1.4.11 (Aug 27, 2013)
+-----------------------------
+
+  * Added mezzatheme themes marketplace to features list - Stephen McDonald
+  * Method to load all symbols of all files in a submodule - Thomas Rega
+  * Use new decorator ``"richhtext_filters"``. The decorator ``"richtext_filter"`` is marked as deprecated - Thomas Rega
+  * Move gallery related tests into the app directory. If the app is not installed, the tests are not executed - Thomas Rega
+  * Move blog related tests into the app directory. If the app is not installed, the tests are not executed - Thomas Rega
+  * Move page related tests into the app directory. If the app is not installed, the tests are not executed - Thomas Rega
+  * Move account related tests into the app directory. If the app is not installed, the tests are not executed - Thomas Rega
+  * Move form related tests into the app directory. If the app is not installed, the tests are not executed - Thomas Rega
+  * Move core related tests into the app tests directory. These tests do not belong direct to an specific app, so they stay. in the core app directory for now - Thomas Rega
+  * Simplify new test module structure - Stephen McDonald
+  * Provide a common TestCase class for all app specific tests, for features such as admin user plus debug cursor for query tracking. Also consistent naming for tests - Stephen McDonald
+  * Move tons of tests into their correct apps - Stephen McDonald
+  * Patch ``jquery.overlay`` with ``jquery.browser`` support to work with new jQuery versions. Closes #701 - Stephen McDonald
+  * Force tinyMCE save in ``dynamic_inline.js`` to avoid issues with richtext fields in dynamic inlines and ordering values not correctly handled. Closes #731 - Stephen McDonald
+  * Update dev status classifier in ``setup.py`` - Stephen McDonald
+  * Remove inclusion of ``mezzanine.accounts`` when testing - Zach Gohr
+  * Inject all Mezzanine apps into the temp settings module when Mezzanine itself is being tested - Stephen McDonald
+  * Use setuptools to test on travis - Stephen McDonald
+  * Apply skipTests throughout different tests where apps are coupled - Stephen McDonald
+  * ``setup.py`` specifies the test deps so we don't need to grab them for travis now - Stephen McDonald
+  * Update ``send_mail_template`` to pass optional email headers to the EmailMultiAlternatives constructor. Rather than having the form ``page_processor`` send mail from user submitted email addresses (if present) have it specify the Reply-To header - Josh Cartmell
+  * Get rid of ``FORMS_DISABLE_SEND_FROM_EMAIL_FIELD``, always add the Reply-To header if there is an ``email_to`` - Josh Cartmell
+  * Adding template accessible settings into context for rendering templates for emails - Danny Sag
+  * Handling case when diff between min and max count is smaller than size. Weights were not calculated correctly when difference between `max_count` and `min_count` was smaller than `settings.TAG_CLOUD_SIZES`. Changed calculation of weights to use floating point arithmetic. The results of weight calculations using old and new code are shown below: ``http://ideone.com/fXs5aG`` - Ahmet Bakan
+  * Adding ``.control-label`` to ``form_fields.html`` - Troy Harvey
+  * Indent ``.control-label`` - Troy Harvey
+  * Be a bit more explicit with request arg in settings context processor - Stephen McDonald
+  * Added mezzanine-meze to third-party apps list - Stephen McDonald
+  * Added support for Django 1.6. - The situations in which ``contribute_to_class`` is called have changed. - Fixed DeprecationWarning about simplejson. - Explicitly set the ``TEST_RUNNER`` to the pre 1.6 one. - Set default=False on BooleanField - Rocky Meza
+  * Keep django version pinned - Stephen McDonald
+  * Ensure correct arguments are used when returning a Page in place of a 404 from a non-page urlpattern - Ben Ledbury
+  * Better error propagation when querying for tweets - Stephen McDonald
+  * Added --force option to ``poll_twitter`` command which will query for tweets on all queries - Stephen McDonald
+  * Catch and show twitter query errors in management command, and allow continuing - Stephen McDonald
+  * Allow twitter queries to gracefully fail in templates - Stephen McDonald
+  * Bump requeusts-oauthlib version. Closes #764 - Stephen McDonald
+  * Exempt Link pages from 404 Page replacement - Ben Ledbury
+  * Changed 'form' to ``'editable_form'`` to fix naming conflict. Editable JS no longer being pulled in - Nicole Harris
+  * Don't quote bullets,. The indentation causes the bullets to be treated as blockquotes - David Winterbottom
+  * ,but do quote quotes :grinning: - David Winterbottom
+  * Use correct comment field name in akismet API. Closes #768 - Stephen McDonald
+  * Added TimeStamped model mixin to Displayable, for created/updated timestamps on all models. Closes #661 - Stephen McDonald
+  * Allow account signups with profiles containing non-nullable fields. Closes #749 - Stephen McDonald
+
+Version 1.4.10 (Jul 29, 2013)
+-----------------------------
+
+  * Added ``window.__language_code`` variable to admin and inline loader - Artem Gluvchynsky
+  * Better error message for page models that get removed from ``INSTALLED_APPS``. Closes #722 - Stephen McDonald
+  * Allow initial user creation in syncdb when a profile model is managed by migrations and doesn't yet exist - Stephen McDonald
+  * Looser AJAX response check for page reordering. Closes #727 - Stephen McDonald
+  * Allow key settings to be defined in fab conf and injected into live ``local_settings`` module - Stephen McDonald
+  * Added valid Polish messages for mezzanine/core. Closes #729 - Marek Wywiał
+  * add a ``tox.ini`` config file - jferry
+  * Use protocol-relative URL to avoid SSL warnings - Vinod Kurup
+  * Make running fabfile outside project root optional, since it conflicts with importing the fabfile into other fabfiles - Stephen McDonald
+  * Specify minimum version of pytz requirement - Vinod Kurup
+  * Fixed view and JS to be compatible with jQuery 1.8 - Ethan Goldstine
+  * Fix ``gravatar_url`` tag for non-ascii email addresses. Closses #721 - Stephen McDonald
+
+Version 1.4.9 (Jul 11, 2013)
+----------------------------
+
+  * Allow deployments to be run from project subdirectories - Stephen McDonald
+  * Add support for ``settings.RICHTEXT_FILTERS``. ``RICHTEXT_FILTERS`` is a list of items that are valid for the. ``RICHTEXT_FILTER`` setting. The plural version takes precedence if it is. available and non-empty. Each item in ``RICHTEXT_FILTERS`` is applied in. order. An alias for the ``richtext_filter`` template filter has been added to. match the plural nature of the new setting: ``richtext_filters`` simply. calls on ``richtext_filter`` for its output - Tim Valenta
+  * Fixed blog post categories list in ``blog_post_list.html`` template - Artem Gluvchynsky
+  * Removed redundant jQuery media from KeywordsWidget - Artem Gluvchynsky
+  * Use urljoin in ``Page.get_absolute_url`` for link pages - Dheeraj Sayala
+  * RTL: fix position of changelink icon in page tree after recent changes. Problem introduced in aec1a0462b60, which solves an issue due to long. page names - Ahmad Khayyat
+  * Comma separate categories in blog post listing - Stephen McDonald
+  * Update docs for new ``RICHTEXT_FILTERS`` setting - Stephen McDonald
+  * Properly deprecate ``RICHTEXT_FILTER`` setting in favour of ``RICHTEXT_FILTERS`` (plural) setting - Stephen McDonald
+  * Update templates to use new ``richtext_filters`` (plural) tag - Stephen McDonald
+  * Allow a single BCC address in addition to list/tuple. BCC fails if the ``addr_bcc`` argument is a single address rather than a list/tuple. This commit wraps a single address in a list to fix this problem - Alex Hill
+  * Make sure ``request._messages`` has been set before trying to access it. This is for cases where the MessageMiddleware hasn't had a chance to. run, ``e.g`` when a previous middleware returned an exception - Gu1
+  * Use a separate key setting for nevercache tokens - Stephen McDonald
+  * Remove print - Stephen McDonald
+  * Add ``is_current_parent`` on pages filtering - Antoine Catton
+  * Remove field related to Django built-in user model. South is expecting those fields to be in the database. So it is. selecting them, since some custom user models don't have them, this can. break this migration - Antoine Catton
+
+Version 1.4.8 (Jun 27, 2013)
+----------------------------
+
+  * Fix nginx config to work on more recent ubuntu versions. Not sure how backwards compatible this is. Please see: ``http://stackoverflow.com/questions/8768946/dealing-with-nginx-400-the-plain-http-request-was-sent-to-https-port-error`` - David Novakovic
+  * dynamically generate top margin of admin content area - Andromeda Yelton
+  * contentMargin out of global namespace - Andromeda Yelton
+  * Force csrf token generation on every request with cache middleware. Closes #676 - Stephen McDonald
+  * Use a more explicit name in ``PageAdmin.get_content_models`` which won't collide with a commonly used field name such as name - Stephen McDonald
+  * Don't use ``ugettext_lazy`` for form field labels since Django will double-escape them. Closes #682 - Stephen McDonald
+  * Move case-insensitive keyword creation into KeywordManager, and allow for duplicate results. Closes #679 - Stephen McDonald
+  * Fix ``ADD_PAGE_ORDER``. Closes #681 - Stephen McDonald
+  * Fix uses of next param for redirects where param exists but value is empty - Stephen McDonald
+  * Fix invalid migration - Stephen McDonald
+  * Revert fix to #594 #677 - causes issues with status messages - Stephen McDonald
+  * TagCloser - don't close br and image tags - John Groszko
+  * Test changes to TagCloser - John Groszko
+  * Clean up some docstrings - Stephen McDonald
+  * When using search against an abstract model (eg Displayable), filter the combined models searched against by the models represented in the ``SEARCH_MODEL_CHOICES`` setting. Closes #684 - Stephen McDonald
+  * Add a note to search docs about ``SEARCH_MODEL_CHOICES`` affecting abstract search behaviour - Stephen McDonald
+  * Added missing class to collapsible navbar that affected nested menus - Jason Wong
+  * SS: Moved to the original - Sachin Shende
+  * long title : break words on pages tree - jferry
+  * SS: Changes done to Twitter app to upgrade to API 1.1. 1. Added ``requests==1.2.3`` and ``requests-oauthlib==0.3.2`` to the dependency list. 2. Added 4 new keys to the settings. 3. Changed models to use new authentication for Twitter API, changed urls and other changes to parse the response - Sachin Shende
+  * use of staticfiles to get url to tinymce - Eduardo S. Klein
+  * Just added my Website to the gallery ;) - Rafael Beckel
+  * More consistent names and validation of new twitter settings - Stephen McDonald
+  * Document new requirements for Twitter API - Stephen McDonald
+  * Fix for Issue #691 - ``ACCOUNTS_APPROVAL_REQUIRED`` bypasses ``ACCOUNTS_VERIFICATION_REQUIRED`` - Ling Thio
+  * Provide better default for ``FILE_UPLOAD_PERMISSIONS`` - Stephen McDonald
+  * fixed little firefox bug - jferry
+  * Bump grappelli-safe version - Stephen McDonald
+  * Improved ssl cipher settings in default nginx conf - Stephen McDonald
+
+Version 1.4.7 (May 18, 2013)
+----------------------------
+
+  * Added the ``ACCOUNTS_NO_USERNAME`` setting, which will hide the username field from signup/update forms, but still generate a unique username for use in profile view slugs - Stephen McDonald
+  * Allow querystring vars to be excluded from pagination links - Stephen McDonald
+  * Missing migration on site perms. Closes #655 - Stephen McDonald
+  * Added support for ``setup.py`` test - Stephen McDonald
+  * Pass in the user to ``page.get_ascendants`` in the page view. This will allow previewing of the unpublished children pages of. unpublished parent pages. fixes #653 - Rocky Meza
+  * Lowered ``MAX_POSTS_PER_CALL`` to 20; Added support for question/answer posts - Jeff Fein-Worton
+  * Use a context instance when rendering page menus, huge performance boost - Stephen McDonald
+  * Fixed rss import errors - Andrey Zhukov
+  * Fixed the igrations to be able to run with a custom user model. This uses a pattern copied from django-reversion: ``https://github.com/etianen/django-reversion/blob/master/src/reversion/migrations/0001_initial.py`` - Rocky Meza
+  * Add ``addr_bcc`` arg to ``send_mail_template``. This accommodates the new setting ``SHOP_ORDER_EMAIL_BCC`` in Cartridge - Alex Hill
+  * Fix lookup for username generation when ``ACCOUNTS_NO_USERNAME`` is True, closes #664 - Stephen McDonald
+  * Fixed 0005 migration wrt custom user models - Rocky Meza
+  * Correctly validate float settings in ``mezzanine.conf`` - Stephen McDonald
+  * Added some validation in the createdb command that fails if a Mezzanine table exists, to prevent people from running it and accidentally faking new migrations that need to be run - Stephen McDonald
+  * ``mezzanine/accounts/templates/email/account_approved.html:`` removed the extra. "http://" - Alexandre Hajjar
+  * Make fabfile work in Windows. Two small changes allow deployment via Fabric from Windows: * Use ``posixpath.join`` instead of ``os.path.join`` to construct all paths destined for the remote machine. * Check for ``"fab-file.py"`` as well as "fab" in ``sys.argv``, to handle the way setuptools-generated command-line scripts work in Windows - Alex Hill
+  * Fix urlpattern for archive year - Stephen McDonald
+  * Hide printing ``STATIC_ROOT`` in deploys - Stephen McDonald
+  * Added paragraph to ``mezzanine/docs/user-accounts.rst`` about ``ACCOUNTS_NO_USERNAME``. setting - Alexandre Hajjar
+  * Used ``username_label`` variable in the PasswordResetForm label. ``(accounts/forms.py)`` - Alexandre Hajjar
+  * Pin html5lib, see ``https://github.com/jsocol/bleach/issues/94`` - Stephen McDonald
+  * Added an extra safeguard for type errors in editable settings - Stephen McDonald
+
+Version 1.4.6 (Apr 28, 2013)
+----------------------------
+
+  * Fix ``set_dynamic_settings`` for projects without ``AUTHENTICATION_BACKENDS`` defined - Stephen McDonald
+  * Provide meaningful exception when dotted import fails - Sam Kingston
+  * SS: Line 12 ``dsq.src`` changed to include https if the site is runnning on SSL. Comments do not appear if the site is running on SSL and js link is http - Sachin Shende
+  * Adding Golds Gym Utah - Josh Batchelor
+  * If ``static_directory`` does not exist, create it. Instead of trying to tar the static directory (which. fails when the dir does not exist), we create it when. is missing - José Aliste
+  * Hack for generic fields that allows MySQL migrations to run correctly - Stephen McDonald
+  * Don't assume a site exists in some older migrations - Stephen McDonald
+  * Use consistent language for 'log in / sign up' - Stephen McDonald
+  * The ``db_type`` field must take a second 'connection' argument, even though unused, otherwise one gets an 'unexpected keyword argument connection' TypeError - Marcos Scriven
+  * Added a port of Django's RedirectFallbackMiddleware with support for Mezzanine's multi-site handling. Closes #535 - Stephen McDonald
+  * Changelist view signature change to work with reversion - Thejaswi Puthraya
+  * Mark redirects middleware as unused if redirects not installed - Stephen McDonald
+  * Add special handling in PageMiddleware for non-page views that raise 404s, but do so with a valid page slug - in this case, we use the page view instead, which allows pages to be created that may match non-page urlpatterns. Closes #561 - Stephen McDonald
+  * Fix CSRF token generation when cache is enabled, should solve #632 - Gu1
+  * Be more explicit in checking for a test run management command - Stephen McDonald
+  * Add missing reference for link - Thibault J.
+  * Fix ``SearchableManager._search_fields`` incorrectly persisting across managers for model subclasses. Closes #633 - Stephen McDonald
+  * Add code of conduct - Ken Bolton
+  * New mezzanine-file-collections reference. mezzanine-media-library got renamed to mezzanine-file-collections. The reference was updated in this commit - Thibault J.
+  * Added the bool setting ``ACCOUNTS_APPROVAL_REQUIRED``, which defaults to False and when set to True, sets newly created public user accounts to inactivate, requiring activation by a staff member. Also added the setting ``ACCOUNTS_APPROVAL_EMAILS`` which can contain a comma separated string of email addresses to send notification emails to each time a new account is created and requires activation. Closes #417 - Stephen McDonald
+  * Document the new account approval feature - Stephen McDonald
+  * Better name for ``emails_list`` -> ``split_addresses`` - Stephen McDonald
+  * Bump grappelli-safe version - Stephen McDonald
+  * Fix thumbnail template tag for palette-mode images. Closes #636 - Stephen McDonald
+  * Added ``select_related`` for user in ``blog_recent_posts`` template tag - Stephen McDonald
+  * Fix lookup of initial data in from-builder forms, and correctly handle initial values for checkbox fields - Stephen McDonald
+  * Allow forms-builder forms to contain template code for default values - Stephen McDonald
+  * Provide more granular export filtering for multiple-choice fields in forms-builder export, eg matches/doesn't match any/all selected choices, and also allow range filters to use only one boundary - Stephen McDonald
+  * Fix ``static_proxy`` to work with //host ``STATIC_URLs``. ``STATIC_URL`` = ``'//mybucket.s3.amazonaws.com'`` would break the ``static_proxy`` prefix stripper, and therefore break tinyMCE plugins. This fix adds proper handling of generic-protocol hostnames to the ``static_proxy`` view - Gabe Smedresman
+  * Reorder blog and accounts patterns in ``mezzanine.urls`` to allow for projects with a blog homepage that also have accounts enabled - Stephen McDonald
+  * Fix handling of paths in zip imports in galleries app - Stephen McDonald
+  * accounts: properly reject multiple matching e-mail addresses. Django allows multiple Users with the same e-mail address; the existing. form can throw MultipleObjectsReturned when get(email=email) is called. against such a dataset - mike wakerly
+  * Added default wsgi script to project template - Stephen McDonald
+  * Only add input-xlarge on inputs without a class attribute, fixes #643 - Gu1
+  * Replaced the ``BLOG_URLS_USE_DATE`` setting with a new ``BLOG_URLS_DATE_FORMAT`` setting - it can contain the string year, month, or day, which controls the date granularity in blog post URLs - Stephen McDonald
+  * Editable settings refactor - this change is to clear up confusion around editable settings being defined in a project's settings module. Previously when this happened, the ``settings.py`` module value would only serve as a default, which would be superceded by the db editable value as soon as the settings admin form is first saved. To address this, this change means that editable settings defined in the project's ``settings.py`` module now mark the setting as not editable, so it will always be the value used. We also include some handling for the migration case so that even with this change, editable settings already in the db that have a ``settings.py`` value defined will still use the db value and provide a warning - Stephen McDonald
+  * Revert the handling for still using db values for editable settings with ``settings.py`` values defined, since it basically defeats the purpose if a ``settings.py`` value is added once a project is live - Stephen McDonald
+  * Added ``INLINE_EDITING_ENABLED`` setting - Jeff Fein-Worton
+  * New ``INLINE_EDITING_ENABLED`` setting doesn't need to be editable - Stephen McDonald
+  * Don't force lowercase keywords. Closes #647 - Stephen McDonald
+  * Allow blog feed title and description to be overridden - Stephen McDonald
+  * Use callable description in atom rss feed - Stephen McDonald
+  * Properly escape comments in ``comment_filter`` template tag - Stephen McDonald
+  * Bump grappelli/filebrowser versions - Stephen McDonald
+
 Version 1.4.5 (Apr 03, 2013)
 ----------------------------
 
   * Fix tweets/comments css - Stephen McDonald
   * RTL: adjust admin navbar thickness after the js->css change - Ahmad Khayyat
   * Provide optional template for user panel in nav - Stephen McDonald
+  * RTL: fix position of help icon in ``filter_horizontal`` m2m widget - Ahmad Khayyat
   * Remove content from DisplayableAdmin's ``search_fields`` since content is not defined on Displayable and may or may not be present on a model that subclasses it and uses the DisplayableAdmin - Josh Cartmell
   * Clean up nav version of user panel - Stephen McDonald
   * Don't strip any HTML in TinyMCE since filtering is handled by bleach - Stephen McDonald
 architecture, ORM, templating, caching and an automatic admin
 interface, Mezzanine provides the following:
 
-  * Hierarchical page navigation
-  * Save as draft and preview on site
-  * Scheduled publishing
-  * Drag-and-drop page ordering
-  * WYSIWYG editing
-  * `In-line page editing`_
-  * Drag-and-drop HTML5 forms builder with CSV export
-  * SEO friendly URLs and meta data
-  * Shopping cart module (`Cartridge`_)
-  * Configurable `dashboard`_ widgets
-  * Blog engine
-  * Tagging
-  * User accounts and profiles with email verification
-  * Translated to over 20 languages
-  * Sharing via Facebook or Twitter
-  * `Custom templates`_ per page or blog post
-  * `Twitter Bootstrap`_ integration
-  * API for `custom content types`_
-  * `Search engine and API`_
-  * Seamless integration with third-party Django apps
-  * Multi-device detection and template handling
-  * One step migration from other blogging engines
-  * Automated production provisioning and deployments
-  * `Disqus`_ integration, or built-in threaded comments
-  * `Gravatar`_ integration
-  * `Google Analytics`_ integration
-  * `Twitter`_ feed integration
-  * `bit.ly`_ integration
-  * `Akismet`_ spam filtering
-  * Built-in `test suite`_
-  * `JVM`_ compatible (via `Jython`_)
+* Hierarchical page navigation
+* Save as draft and preview on site
+* Scheduled publishing
+* Drag-and-drop page ordering
+* WYSIWYG editing
+* `In-line page editing`_
+* Drag-and-drop HTML5 forms builder with CSV export
+* SEO friendly URLs and meta data
+* Shopping cart module (`Cartridge`_)
+* Configurable `dashboard`_ widgets
+* Blog engine
+* Tagging
+* `Themes Marketplace`_
+* User accounts and profiles with email verification
+* Translated to over 20 languages
+* Sharing via Facebook or Twitter
+* `Custom templates`_ per page or blog post
+* `Twitter Bootstrap`_ integration
+* API for `custom content types`_
+* `Search engine and API`_
+* Seamless integration with third-party Django apps
+* Multi-device detection and template handling
+* One step migration from other blogging engines
+* Automated production provisioning and deployments
+* `Disqus`_ integration, or built-in threaded comments
+* `Gravatar`_ integration
+* `Google Analytics`_ integration
+* `Twitter`_ feed integration
+* `bit.ly`_ integration
+* `Akismet`_ spam filtering
+* Built-in `test suite`_
+* `JVM`_ compatible (via `Jython`_)
 
 The Mezzanine admin dashboard:
 
 Mezzanine makes use of as few libraries as possible (apart from a
 standard Django environment), with the following dependencies:
 
-  * `Python`_ 2.6 / 2.7
-  * `Django`_ 1.4 / 1.5
-  * `Python Imaging Library`_ - for image resizing
-  * `grappelli-safe`_ - admin skin (`Grappelli`_ fork)
-  * `filebrowser-safe`_ - for managing file uploads (`FileBrowser`_ fork)
-  * `bleach`_ - for sanitizing markup in content
-  * `pytz`_ - for timezone support
-  * `South`_ - for database migrations (optional)
-  * `django-compressor`_ - for merging JS/CSS assets (optional)
-  * `pyflakes`_ and `pep8`_ - for running the test suite (optional)
+* `Python`_ 2.6 / 2.7
+* `Django`_ 1.4 / 1.5
+* `Python Imaging Library`_ - for image resizing
+* `grappelli-safe`_ - admin skin (`Grappelli`_ fork)
+* `filebrowser-safe`_ - for managing file uploads (`FileBrowser`_ fork)
+* `bleach`_ - for sanitizing markup in content
+* `pytz`_ - for timezone support
+* `South`_ - for database migrations (optional)
+* `django-compressor`_ - for merging JS/CSS assets (optional)
+* `requests`_ and `requests-oauth`_ - for interacting with external APIs
+* `pyflakes`_ and `pep8`_ - for running the test suite (optional)
 
 Browser Support
 ===============
 
 Please note the following guidelines for contributing:
 
-  * Contributed code must be written in the existing style. This is
-    as simple as following the `Django coding style`_ and (most
-    importantly) `PEP 8`_.
-  * Contributions must be available on a separately named branch
-    based on the latest version of the main branch.
-  * Run the tests before committing your changes. If your changes
-    cause the tests to break, they won't be accepted.
-  * If you are adding new functionality, you must include basic tests
-    and documentation.
+* Contributed code must be written in the existing style. This is
+  as simple as following the `Django coding style`_ and (most
+  importantly) `PEP 8`_.
+* Contributions must be available on a separately named branch
+  based on the latest version of the main branch.
+* Run the tests before committing your changes. If your changes
+  cause the tests to break, they won't be accepted.
+* If you are adding new functionality, you must include basic tests
+  and documentation.
 
 If you want to do development with mezzanine, here's a quick way to set
 up a development environment and run the unit tests, using
     $ cp mezzanine/project_template/local_settings.py.template mezzanine/project_template/local_settings.py
     $ ./mezzanine/project_template/manage.py test
 
-
 Language Translations
 =====================
 
 list it here, send an email to the `mezzanine-users`_ mailing list.
 You can also add modules to the `Mezzanine Grid on djangopackages.com`_.
 
-  * `mezzanine-html5boilerplate`_ - Integrates the
-    `html5boilerplate project`_  into Mezzanine.
-  * `mezzanine-mdown`_ - Adds `Markdown`_ support to Mezzanine's rich
-    text editor.
-  * `mezzanine-openshift`_ - Setup for running Mezzanine on
-    `Redhat's OpenShift`_ cloud platform.
-  * `mezzanine-stackato`_ - Setup for running Mezzanine on
-    `ActiveState's Stackato`_ cloud platform.
-  * `mezzanine-blocks`_ - A Mezzanine flavored fork of
-    django-flatblocks.
-  * `mezzanine-widgets`_ - Widget system for Mezzanine.
-  * `mezzanine-themes`_ - A collection of Django/Mezzanine templates.
-  * `mezzanine-twittertopic`_ - Manage multiple Twitter topic feeds
-    from the Mezzanine admin interface.
-  * `mezzanine-captcha`_ - Adds CAPTCHA field types to Mezzanine's
-    forms builder app.
-  * `mezzanine-bookmarks`_ - A multi-user bookmark app for Mezzanine.
-  * `mezzanine-events`_ - Events plugin for Mezzanine, with geocoding
-    via Google Maps, iCalendar files, webcal URLs and directions via
-    Google Calendar/Maps.
-  * `mezzanine-polls`_ - Polls application for Mezzanine.
-  * `mezzanine-pagedown`_ - Adds the `Pagedown`_ WYSIWYG editor to
-    Mezzanine.
-  * `mezzanine-careers`_ - Job posting application for Mezzanine.
-  * `mezzanine-recipes`_ - Recipes plugin with built-in REST API.
-  * `mezzanine-slides`_ - Responsive banner slides app for Mezzanine.
-  * `mezzyblocks`_ - Another app for adding blocks/modules to Mezzanine.
-  * `mezzanine-flexipage`_ - Allows designers to manage content areas
-    in templates.
-  * `mezzanine-instagram`_ - A simple Instagram app for Mezzanine.
-  * `mezzanine-wiki`_ - Wiki app for Mezzanine.
-  * `mezzanine-calendar`_ - Calendar pages in Mezzanine
-  * `mezzanine-facebook`_ - Simple Facebook integration for Mezzanine.
-  * `mezzanine-instagram-gallery`_ - Create Mezzanine galleries using
-    Instagram images.
-  * `mezzanine-cli`_ - Command-line interface for Mezzanine.
-  * `mezzanine-categorylink`_ - Integrates Mezzanine's Link pages with
-    its blog categories.
-  * `mezzanine-podcast`_ - A simple podcast streamer and manager for
-    Mezzanine.
-  * `mezzanine-linkcollection`_ - Collect links. Feature them. Share
-    them over RSS.
-  * `cash-generator`_ - Generate `GnuCash`_ invoices with Mezzanine.
-  * `mezzanine-foundation`_ - `Zurb Foundation`_ theme for Mezzanine.
+* `Cartridge`_ - ecommerce for Mezzanine.
+* `Drum`_ - A `Hacker News`_ / `Reddit`_ clone powered by Mezzanine.
+* `mezzanine-html5boilerplate`_ - Integrates the
+  `html5boilerplate project`_  into Mezzanine.
+* `mezzanine-mdown`_ - Adds `Markdown`_ support to Mezzanine's rich
+  text editor.
+* `mezzanine-openshift`_ - Setup for running Mezzanine on
+  `Redhat's OpenShift`_ cloud platform.
+* `mezzanine-stackato`_ - Setup for running Mezzanine on
+  `ActiveState's Stackato`_ cloud platform.
+* `mezzanine-blocks`_ - A Mezzanine flavored fork of
+  django-flatblocks.
+* `mezzanine-widgets`_ - Widget system for Mezzanine.
+* `mezzanine-themes`_ - A collection of Django/Mezzanine templates.
+* `mezzanine-twittertopic`_ - Manage multiple Twitter topic feeds
+  from the Mezzanine admin interface.
+* `mezzanine-captcha`_ - Adds CAPTCHA field types to Mezzanine's
+  forms builder app.
+* `mezzanine-bookmarks`_ - A multi-user bookmark app for Mezzanine.
+* `mezzanine-events`_ - Events plugin for Mezzanine, with geocoding
+  via Google Maps, iCalendar files, webcal URLs and directions via
+  Google Calendar/Maps.
+* `mezzanine-polls`_ - Polls application for Mezzanine.
+* `mezzanine-pagedown`_ - Adds the `Pagedown`_ WYSIWYG editor to
+  Mezzanine.
+* `mezzanine-careers`_ - Job posting application for Mezzanine.
+* `mezzanine-recipes`_ - Recipes plugin with built-in REST API.
+* `mezzanine-slides`_ - Responsive banner slides app for Mezzanine.
+* `mezzyblocks`_ - Another app for adding blocks/modules to Mezzanine.
+* `mezzanine-flexipage`_ - Allows designers to manage content areas
+  in templates.
+* `mezzanine-instagram`_ - A simple Instagram app for Mezzanine.
+* `mezzanine-wiki`_ - Wiki app for Mezzanine.
+* `mezzanine-calendar`_ - Calendar pages in Mezzanine
+* `mezzanine-facebook`_ - Simple Facebook integration for Mezzanine.
+* `mezzanine-instagram-gallery`_ - Create Mezzanine galleries using
+  Instagram images.
+* `mezzanine-cli`_ - Command-line interface for Mezzanine.
+* `mezzanine-categorylink`_ - Integrates Mezzanine's Link pages with
+  its blog categories.
+* `mezzanine-podcast`_ - A simple podcast streamer and manager for
+  Mezzanine.
+* `mezzanine-linkcollection`_ - Collect links. Feature them. Share
+  them over RSS.
+* `cash-generator`_ - Generate `GnuCash`_ invoices with Mezzanine.
+* `mezzanine-foundation`_ - `Zurb Foundation`_ theme for Mezzanine.
+* `mezzanine-file-collections`_ - Simple file collection page type
+  for Mezzanine.
+* `mezzanine-wymeditor`_ - `WYMeditor`_ adapted as the rich text
+  editor for Mezzanine.
+* `mezzanine-meze`_ - Adds support for `reStructuredText`_,
+  `Pygments`_ and more, to Mezzanine's rich text editing.
+* `mezzanine-pageimages`_ - Add background and banner images per page
+  in Mezzanine.
+* `mezzanine-protected-pages`_ - Restrict access to pages by group
+  membership.
 
 Donating
 ========
 `GitHub issue tracker`_. And feel free to drop by the `#mezzanine
 IRC channel`_ on `Freenode`_, for a chat.
 
+Communications in all Mezzanine spaces are expected to conform
+to the `Django Code of Conduct`_.
+
 Sites Using Mezzanine
 =====================
 
-  * `Citrus Agency <http://citrus.com.au/>`_
-  * `Mezzanine Project <http://mezzanine.jupo.org>`_
-  * `Nick Hagianis <http://hagianis.com>`_
-  * `Thomas Johnson <http://tomfmason.net>`_
-  * `Central Mosque Wembley <http://wembley-mosque.co.uk>`_
-  * `Ovarian Cancer Research Foundation <http://ocrf.com.au/>`_
-  * `The Source Procurement <http://thesource.com.au/>`_
-  * `Imageinary <http://imageinary.com>`_
-  * `Brad Montgomery <http://blog.bradmontgomery.net>`_
-  * `Jashua Cloutier <http://www.senexcanis.com>`_
-  * `Alpha & Omega Contractors <http://alphaomegacontractors.com>`_
-  * `Equity Advance <http://equityadvance.com.au/>`_
-  * `Head3 Interactive <http://head3.com>`_
-  * `PyLadies <http://www.pyladies.com>`_
-  * `Ripe Maternity <http://www.ripematernity.com/>`_
-  * `Cotton On <http://shop.cottonon.com/>`_
-  * `List G Barristers <http://www.listgbarristers.com.au>`_
-  * `Tri-Cities Flower Farm <http://www.tricitiesflowerfarm.com>`_
-  * `daon.ru <http://daon.ru/>`_
-  * `autoindeks.ru <http://autoindeks.ru/>`_
-  * `immiau.ru <http://immiau.ru/>`_
-  * `ARA Consultants <http://www.araconsultants.com.au/>`_
-  * `Boîte à Z'images <http://boiteazimages.com/>`_
-  * `The Melbourne Cup <http://www.melbournecup.com/>`_
-  * `Diablo News <http://www.diablo-news.com>`_
-  * `Goldman Travel <http://www.goldmantravel.com.au/>`_
-  * `IJC Digital <http://ijcdigital.com/>`_
-  * `Coopers <http://store.coopers.com.au/>`_
-  * `Joe Julian <http://joejulian.name>`_
-  * `Sheer Ethic <http://sheerethic.com/>`_
-  * `Salt Lake Magazine <http://saltlakemagazine.com/>`_
-  * `Boca Raton Magazine <http://bocamag.com/>`_
-  * `Photog.me <http://www.photog.me>`_
-  * `Elephant Juice Soup <http://www.elephantjuicesoup.com>`_
-  * `National Positions <http://www.nationalpositions.co.uk/>`_
-  * `Like Humans Do <http://www.likehumansdo.com>`_
-  * `Connecting Countries <http://connectingcountries.net>`_
-  * `tindie.com <http://tindie.com>`_
-  * `Environmental World Products <http://ewp-sa.com/>`_
-  * `Ross A. Laird <http://rosslaird.com>`_
-  * `Etienne B. Roesch <http://etienneroes.ch>`_
-  * `Recruiterbox <http://recruiterbox.com/>`_
-  * `Mod Productions <http://modprods.com/>`_
-  * `Appsembler <http://appsembler.com/>`_
-  * `Pink Twig <http://www.pinktwig.ca>`_
-  * `Parfume Planet <http://parfumeplanet.com>`_
-  * `Trading 4 Us <http://www.trading4.us>`_
-  * `Chris Fleisch <http://chrisfleisch.com>`_
-  * `Theneum <http://theneum.com/>`_
-  * `My Story Chest <http://www.mystorychest.com>`_
-  * `Philip Sahli <http://www.fatrix.ch>`_
-  * `Raymond Chandler <http://www.codearchaeologist.org>`_
-  * `Nashsb <http://nashpp.com>`_
-  * `AciBASE <http://acinetobacter.bham.ac.uk>`_
-  * `Enrico Tröger <http://www.uvena.de>`_
-  * `Matthe Wahn <http://www.matthewahn.com>`_
-  * `Bit of Pixels <http://bitofpixels.com>`_
-  * `European Crystallographic Meeting <http://ecm29.ecanews.org>`_
-  * `Dreamperium <http://dreamperium.com>`_
-  * `UT Dallas <http://utdallasiia.com>`_
-  * `Go Yama <http://goyamamusic.com>`_
-  * `Yeti LLC <http://www.yetihq.com/>`_
-  * `Li Xiong <http://idhoc.com>`_
-  * `Pageworthy <http://pageworthy.com>`_
-  * `Prince Jets <http://princejets.com>`_
-  * `30 sites in 30 days <http://1inday.com>`_
-  * `St Barnabas' Theological College <http://www.sbtc.org.au>`_
-  * `Helios 3D <http://helios3d.nl/>`_
-  * `Life is Good <http://lifeisgoodforall.co.uk/>`_
-  * `Brooklyn Navy Yard <http://bldg92.org/>`_
-  * `Pie Monster <http://piemonster.me>`_
-  * `Cotton On Asia <http://asia.cottonon.com/>`_
-  * `Ivan Diao <http://www.adieu.me>`_
-  * `Super Top Secret <http://www.wearetopsecret.com/>`_
-  * `Jaybird Sport <http://www.jaybirdgear.com/>`_
-  * `Manai Glitter <https://manai.co.uk>`_
-  * `Sri Emas International School <http://www.sriemas.edu.my>`_
-  * `Boom Perun <http://perunspace.ru>`_
-  * `Tactical Bags <http://tacticalbags.ru>`_
-  * `apps.de <http://apps.de>`_
-  * `Sunfluence <http://sunfluence.com>`_
-  * `ggzpreventie.nl <http://ggzpreventie.nl>`_
-  * `dakuaiba.com <http://www.dakuaiba.com>`_
-  * `Wdiaz <http://www.wdiaz.org>`_
-  * `Hunted Hive <http://huntedhive.com/>`_
-  * `mjollnir.org <http://mjollnir.org>`_
-  * `The Beancat Network <http://www.beancatnet.org>`_
-  * `Raquel Marón <http://raquelmaron.com/>`_
-  * `EatLove <http://eatlove.com.au/>`_
-  * `Hospitality Quotient <http://hospitalityq.com/>`_
-  * `The Andrew Story <http://theandrewstory.com/>`_
-  * `Charles Koll Jewelry <http://charleskoll.com/>`_
-  * `Mission Healthcare <http://homewithmission.com/>`_
-  * `Creuna (com/dk/fi/no/se) <http://www.creuna.com/>`_
-  * `Coronado School of the Arts <http://www.cosasandiego.com/>`_
-  * `SiteComb <http://www.sitecomb.com>`_
-  * `Dashing Collective <http://dashing.tv/>`_
-  * `Puraforce Remedies <http://puraforceremedies.com/>`_
-  * `Google's VetNet <http://www.vetnethq.com/>`_
-  * `1800RESPECT <http://www.1800respect.org.au/>`_
-  * `Evenhouse Consulting <http://evenhouseconsulting.com/>`_
-  * `Humboldt Community Christian School <http://humboldtccs.org>`_
-  * `Atlanta's Living Legacy <http://gradyhistory.com>`_
-  * `Shipgistix <http://shipgistix.com>`_
-  * `Yuberactive <http://www.yuberactive.asia>`_
-  * `Medical Myth Busters <http://pogromcymitowmedycznych.pl>`_
-  * `4player Network <http://4playernetwork.com/>`_
-  * `Top500 Supercomputers <http://top500.org>`_
-  * `Die Betroffenen <http://www.zeichnemit.de>`_
-  * `uvena.de <http://uvena.de>`_
-  * `ezless.com <http://ezless.com>`_
-  * `Dominican Python <http://python.do>`_
-  * `Stackful.io <http://stackful.io/>`_
-  * `Adrenaline <http://www.adrln.com/>`_
-  * `ACE EdVenture Programme <http://aceedventure.com/>`_
-  * `Butchershop Creative <http://www.butchershopcreative.com/>`_
-  * `Sam Kingston <http://www.sjkingston.com>`_
-  * `Ludwig von Mises Institute <http://mises.fi>`_
-  * `Incendio <http://incendio.no/>`_
-  * `Alexander Lillevik <http://lillevikdesign.no/>`_
-  * `Walk In Tromsø <http://www.turitromso.no>`_
-  * `Mandrivia Linux <http://www.mandriva.com/>`_
-  * `Crown Preschool <http://crownpreschool.com>`_
-  * `Coronado Pathways Charter School <http://coronadopathways.com>`_
-  * `Raindrop Marketing <http://www.raindropads.com>`_
-  * `Web4py <http://www.web4py.com>`_
-  * `The Peculiar Store <http://thepeculiarstore.com>`_
-  * `GrinDin <http://www.grindin.ru>`_
-  * `4Gume <http://www.4gume.com>`_
-  * `Skydivo <http://skydivo.com>`_
-  * `Noshly <http://noshly.com>`_
-  * `Kabu Creative <http://kabucreative.com.au/>`_
-  * `KisanHub <http://www.kisanhub.com/>`_
-  * `Your Song Your Story <http://yoursongyourstory.org/>`_
-  * `Kegbot <http://kegbot.org>`_
-  * `Fiz <http://fiz.com/>`_
-  * `Willborn <http://willbornco.com>`_
-  * `Copilot Co <http://copilotco.com>`_
-  * `Amblitec <http://www.amblitec.com>`_
-  * `Gold's Gym Utah <http://www.bestgymever.com/>`_
+* `Citrus Agency <http://citrus.com.au/>`_
+* `Mezzanine Project <http://mezzanine.jupo.org>`_
+* `Nick Hagianis <http://hagianis.com>`_
+* `Thomas Johnson <http://tomfmason.net>`_
+* `Central Mosque Wembley <http://wembley-mosque.co.uk>`_
+* `Ovarian Cancer Research Foundation <http://ocrf.com.au/>`_
+* `The Source Procurement <http://thesource.com.au/>`_
+* `Imageinary <http://imageinary.com>`_
+* `Brad Montgomery <http://blog.bradmontgomery.net>`_
+* `Jashua Cloutier <http://www.senexcanis.com>`_
+* `Alpha & Omega Contractors <http://alphaomegacontractors.com>`_
+* `Equity Advance <http://equityadvance.com.au/>`_
+* `Head3 Interactive <http://head3.com>`_
+* `PyLadies <http://www.pyladies.com>`_
+* `Ripe Maternity <http://www.ripematernity.com/>`_
+* `Cotton On <http://shop.cottonon.com/>`_
+* `List G Barristers <http://www.listgbarristers.com.au>`_
+* `Tri-Cities Flower Farm <http://www.tricitiesflowerfarm.com>`_
+* `daon.ru <http://daon.ru/>`_
+* `autoindeks.ru <http://autoindeks.ru/>`_
+* `immiau.ru <http://immiau.ru/>`_
+* `ARA Consultants <http://www.araconsultants.com.au/>`_
+* `Boîte à Z'images <http://boiteazimages.com/>`_
+* `The Melbourne Cup <http://www.melbournecup.com/>`_
+* `Diablo News <http://www.diablo-news.com>`_
+* `Goldman Travel <http://www.goldmantravel.com.au/>`_
+* `IJC Digital <http://ijcdigital.com/>`_
+* `Coopers <http://store.coopers.com.au/>`_
+* `Joe Julian <http://joejulian.name>`_
+* `Sheer Ethic <http://sheerethic.com/>`_
+* `Salt Lake Magazine <http://saltlakemagazine.com/>`_
+* `Boca Raton Magazine <http://bocamag.com/>`_
+* `Photog.me <http://www.photog.me>`_
+* `Elephant Juice Soup <http://www.elephantjuicesoup.com>`_
+* `National Positions <http://www.nationalpositions.co.uk/>`_
+* `Like Humans Do <http://www.likehumansdo.com>`_
+* `Connecting Countries <http://connectingcountries.net>`_
+* `tindie.com <http://tindie.com>`_
+* `Environmental World Products <http://ewp-sa.com/>`_
+* `Ross A. Laird <http://rosslaird.com>`_
+* `Etienne B. Roesch <http://etienneroes.ch>`_
+* `Recruiterbox <http://recruiterbox.com/>`_
+* `Mod Productions <http://modprods.com/>`_
+* `Appsembler <http://appsembler.com/>`_
+* `Pink Twig <http://www.pinktwig.ca>`_
+* `Parfume Planet <http://parfumeplanet.com>`_
+* `Trading 4 Us <http://www.trading4.us>`_
+* `Chris Fleisch <http://chrisfleisch.com>`_
+* `Theneum <http://theneum.com/>`_
+* `My Story Chest <http://www.mystorychest.com>`_
+* `Philip Sahli <http://www.fatrix.ch>`_
+* `Raymond Chandler <http://www.codearchaeologist.org>`_
+* `Nashsb <http://nashpp.com>`_
+* `AciBASE <http://acinetobacter.bham.ac.uk>`_
+* `Enrico Tröger <http://www.uvena.de>`_
+* `Matthe Wahn <http://www.matthewahn.com>`_
+* `Bit of Pixels <http://bitofpixels.com>`_
+* `European Crystallographic Meeting <http://ecm29.ecanews.org>`_
+* `Dreamperium <http://dreamperium.com>`_
+* `UT Dallas <http://utdallasiia.com>`_
+* `Go Yama <http://goyamamusic.com>`_
+* `Yeti LLC <http://www.yetihq.com/>`_
+* `Li Xiong <http://idhoc.com>`_
+* `Pageworthy <http://pageworthy.com>`_
+* `Prince Jets <http://princejets.com>`_
+* `30 sites in 30 days <http://1inday.com>`_
+* `St Barnabas' Theological College <http://www.sbtc.org.au/>`_
+* `Helios 3D <http://helios3d.nl/>`_
+* `Life is Good <http://lifeisgoodforall.co.uk/>`_
+* `Building 92 <http://bldg92.org/>`_
+* `Pie Monster <http://piemonster.me>`_
+* `Cotton On Asia <http://asia.cottonon.com/>`_
+* `Ivan Diao <http://www.adieu.me>`_
+* `Super Top Secret <http://www.wearetopsecret.com/>`_
+* `Jaybird Sport <http://www.jaybirdgear.com/>`_
+* `Manai Glitter <https://manai.co.uk>`_
+* `Sri Emas International School <http://www.sriemas.edu.my>`_
+* `Boom Perun <http://perunspace.ru>`_
+* `Tactical Bags <http://tacticalbags.ru>`_
+* `apps.de <http://apps.de>`_
+* `Sunfluence <http://sunfluence.com>`_
+* `ggzpreventie.nl <http://ggzpreventie.nl>`_
+* `dakuaiba.com <http://www.dakuaiba.com>`_
+* `Wdiaz <http://www.wdiaz.org>`_
+* `Hunted Hive <http://huntedhive.com/>`_
+* `mjollnir.org <http://mjollnir.org>`_
+* `The Beancat Network <http://www.beancatnet.org>`_
+* `Raquel Marón <http://raquelmaron.com/>`_
+* `EatLove <http://eatlove.com.au/>`_
+* `Hospitality Quotient <http://hospitalityq.com/>`_
+* `The Andrew Story <http://theandrewstory.com/>`_
+* `Charles Koll Jewelry <http://charleskoll.com/>`_
+* `Mission Healthcare <http://homewithmission.com/>`_
+* `Creuna (com/dk/fi/no/se) <http://www.creuna.com/>`_
+* `Coronado School of the Arts <http://www.cosasandiego.com/>`_
+* `SiteComb <http://www.sitecomb.com>`_
+* `Dashing Collective <http://dashing.tv/>`_
+* `Puraforce Remedies <http://puraforceremedies.com/>`_
+* `Google's VetNet <http://www.vetnethq.com/>`_
+* `1800RESPECT <http://www.1800respect.org.au/>`_
+* `Evenhouse Consulting <http://evenhouseconsulting.com/>`_
+* `Humboldt Community Christian School <http://humboldtccs.org>`_
+* `Atlanta's Living Legacy <http://gradyhistory.com>`_
+* `Shipgistix <http://shipgistix.com>`_
+* `Yuberactive <http://www.yuberactive.asia>`_
+* `Medical Myth Busters <http://pogromcymitowmedycznych.pl>`_
+* `4player Network <http://4playernetwork.com/>`_
+* `Top500 Supercomputers <http://top500.org>`_
+* `Die Betroffenen <http://www.zeichnemit.de>`_
+* `uvena.de <http://uvena.de>`_
+* `ezless.com <http://ezless.com>`_
+* `Dominican Python <http://python.do>`_
+* `Stackful.io <http://stackful.io/>`_
+* `Adrenaline <http://www.adrln.com/>`_
+* `ACE EdVenture Programme <http://aceedventure.com/>`_
+* `Butchershop Creative <http://www.butchershopcreative.com/>`_
+* `Sam Kingston <http://www.sjkingston.com>`_
+* `Ludwig von Mises Institute <http://mises.fi>`_
+* `Incendio <http://incendio.no/>`_
+* `Alexander Lillevik <http://lillevikdesign.no/>`_
+* `Walk In Tromsø <http://www.turitromso.no>`_
+* `Mandrivia Linux <http://www.mandriva.com/>`_
+* `Crown Preschool <http://crownpreschool.com>`_
+* `Coronado Pathways Charter School <http://coronadopathways.com>`_
+* `Raindrop Marketing <http://www.raindropads.com>`_
+* `Web4py <http://www.web4py.com>`_
+* `The Peculiar Store <http://thepeculiarstore.com>`_
+* `GrinDin <http://www.grindin.ru>`_
+* `4Gume <http://www.4gume.com>`_
+* `Skydivo <http://skydivo.com>`_
+* `Noshly <http://noshly.com>`_
+* `Kabu Creative <http://kabucreative.com.au/>`_
+* `KisanHub <http://www.kisanhub.com/>`_
+* `Your Song Your Story <http://yoursongyourstory.org/>`_
+* `Kegbot <http://kegbot.org>`_
+* `Fiz <http://fiz.com/>`_
+* `Willborn <http://willbornco.com>`_
+* `Copilot Co <http://copilotco.com>`_
+* `Amblitec <http://www.amblitec.com>`_
+* `Gold's Gym Utah <http://www.bestgymever.com/>`_
+* `Appsin - Blog to Native app <http://apps.in/>`_
+* `Take Me East <http://takemeeast.net>`_
+* `Code Raising <http://www.coderaising.org>`_
+* `ZigZag Bags <http://www.zigzagbags.com.au>`_
+* `VerifIP <http://verifip.com/>`_
+* `Clic TV <http://www.clictv.tv/>`_
+* `JE Rivas <http://www.jerivas.com/>`_
+* `Heather Gregory Nutrition <http://heathergregorynutrition.com>`_
+* `Coronado Island Realty <http://coronado-realty.com>`_
+* `Loans to Homes <http://loanstohomes.com>`_
+* `Gensler Group <http://genslergroup.com>`_
+* `SaniCo <https://sanimedicaltourism.com>`_
+* `Grupo Invista <http://grupoinvista.com>`_
+* `Brooklyn Navy Yard <http://brooklynnavyyard.org/>`_
+* `MEZZaTHEME <http://mezzathe.me/>`_
+* `Nektra Advanced Computing <http://www.nektra.com/>`_
+* `Bootstrap ASAP <https://bootstrapasap.com/>`_
+* `California Center for Jobs <http://www.centerforjobs.org/>`_
+* `Sam Kingston <http://www.sjkingston.com>`_
+* `Code Juggle DJ <http://www.codejuggle.dj>`_
+* `Food News <http://food.hypertexthero.com>`_
+
 
 Quotes
 ======
 
-  * "I'm enjoying working with Mezzanine, it's good work"
-    - `Van Lindberg`_, `Python Software Foundation`_ chairman
-  * "Mezzanine looks like it may be Django's killer app"
-    - `Antonio Rodriguez`_, ex CTO of `Hewlett Packard`_, founder
-    of `Tabblo`_
-  * "Mezzanine looks pretty interesting, tempting to get me off
-    Wordpress" - `Jesse Noller`_, Python core contributor,
-    `Python Software Foundation`_ board member
-  * "I think I'm your newest fan. Love these frameworks"
-    - `Emile Petrone`_, integrations engineer at `Urban Airship`_
-  * "Mezzanine is amazing" - `Audrey Roy`_, founder of `PyLadies`_
-    and `Django Packages`_
-  * "Mezzanine convinced me to switch from the Ruby world over
-    to Python" - `Michael Delaney`_, developer
-  * "Like Linux and Python, Mezzanine just feels right" - `Phil Hughes`_,
-    Linux For Dummies author, `The Linux Journal`_ columnist
-  * "Impressed with Mezzanine so far" - `Brad Montgomery`_, founder
-    of `Work For Pie`_
-  * "From the moment I installed Mezzanine, I have been delighted, both
-    with the initial experience and the community involved in its
-    development" - `John Campbell`_, founder of `Head3 Interactive`_
-  * "You need to check out the open source project Mezzanine. In one
-    word: Elegant" - `Nick Hagianis`_, developer
+* "I'm enjoying working with Mezzanine, it's good work"
+  - `Van Lindberg`_, `Python Software Foundation`_ chairman
+* "Mezzanine looks like it may be Django's killer app"
+  - `Antonio Rodriguez`_, ex CTO of `Hewlett Packard`_, founder
+  of `Tabblo`_
+* "Mezzanine looks pretty interesting, tempting to get me off
+  Wordpress" - `Jesse Noller`_, Python core contributor,
+  `Python Software Foundation`_ board member
+* "I think I'm your newest fan. Love these frameworks"
+  - `Emile Petrone`_, integrations engineer at `Urban Airship`_
+* "Mezzanine is amazing" - `Audrey Roy`_, founder of `PyLadies`_
+  and `Django Packages`_
+* "Mezzanine convinced me to switch from the Ruby world over
+  to Python" - `Michael Delaney`_, developer
+* "Like Linux and Python, Mezzanine just feels right" - `Phil Hughes`_,
+  Linux For Dummies author, `The Linux Journal`_ columnist
+* "Impressed with Mezzanine so far" - `Brad Montgomery`_, founder
+  of `Work For Pie`_
+* "From the moment I installed Mezzanine, I have been delighted, both
+  with the initial experience and the community involved in its
+  development" - `John Campbell`_, founder of `Head3 Interactive`_
+* "You need to check out the open source project Mezzanine. In one
+  word: Elegant" - `Nick Hagianis`_, developer
+
 
 .. GENERAL LINKS
 
 .. _`Django`: http://djangoproject.com/
+.. _`Django Code of Conduct`: https://www.djangoproject.com/conduct/
 .. _`BSD licensed`: http://www.linfo.org/bsdlicense.html
 .. _`Wordpress`: http://wordpress.org/
 .. _`great sites people have built using Mezzanine`: http://mezzanine.jupo.org/sites/
 .. _`pip`: http://www.pip-installer.org/
 .. _`bleach`: http://pypi.python.org/pypi/bleach
 .. _`pytz`: http://pypi.python.org/pypi/pytz/
-.. _`django-compressor`: http://pypi.python.org/pypi/django-compressor/
+.. _`django-compressor`: https://pypi.python.org/pypi/django_compressor
 .. _`Python Imaging Library`: http://www.pythonware.com/products/pil/
 .. _`grappelli-safe`: http://github.com/stephenmcd/grappelli-safe
 .. _`filebrowser-safe`: http://github.com/stephenmcd/filebrowser-safe/
 .. _`Grappelli`: http://code.google.com/p/django-grappelli/
 .. _`FileBrowser`: http://code.google.com/p/django-filebrowser/
 .. _`South`: http://south.aeracode.org/
+.. _`requests`: http://docs.python-requests.org/en/latest/
+.. _`requests-oauth`: https://github.com/maraujop/requests-oauth
 .. _`pyflakes`: http://pypi.python.org/pypi/pyflakes
 .. _`pep8`: http://pypi.python.org/pypi/pep8
 .. _`In-line page editing`: http://mezzanine.jupo.org/docs/inline-editing.html
 .. _`custom content types`: http://mezzanine.jupo.org/docs/content-architecture.html#creating-custom-content-types
 .. _`Search engine and API`: http://mezzanine.jupo.org/docs/search-engine.html
 .. _`dashboard`: http://mezzanine.jupo.org/docs/admin-customization.html#dashboard
+.. _`Themes Marketplace`: http://mezzathe.me/
 .. _`Cartridge`: http://cartridge.jupo.org/
-.. _`Themes`: http://mezzanine.jupo.org/docs/themes.html
 .. _`Custom templates`: http://mezzanine.jupo.org/docs/content-architecture.html#page-templates
 .. _`test suite`: http://mezzanine.jupo.org/docs/packages.html#module-mezzanine.core.tests
 .. _`JVM`: http://en.wikipedia.org/wiki/Java_virtual_machine
 .. _`mezzanine-users`: http://groups.google.com/group/mezzanine-users/topics
 .. _`security@jupo.org`: mailto:security@jupo.org?subject=Mezzanine+Security+Issue
 .. _`GitHub issue tracker`: http://github.com/stephenmcd/mezzanine/issues
-.. _`#mezzanine IRC channel`: irc://freenode.net/mezzanine
+.. _`#mezzanine IRC channel`: irc://irc.freenode.net/mezzanine
 .. _`Freenode`: http://freenode.net
 .. _`Django coding style`: http://docs.djangoproject.com/en/dev/internals/contributing/#coding-style
 .. _`PEP 8`: http://www.python.org/dev/peps/pep-0008/
 
 .. THIRD PARTY LIBS
 
+.. _`Drum`: https://github.com/stephenmcd/drum
+.. _`Hacker News`: https://news.ycombinator.com
+.. _`Reddit`: http://www.reddit.com
+.. _`mezzanine-html5boilerplate`: https://github.com/tvon/mezzanine-html5boilerplate
 .. _`mezzanine-html5boilerplate`: https://github.com/tvon/mezzanine-html5boilerplate
 .. _`html5boilerplate project`: http://html5boilerplate.com/
 .. _`mezzanine-mdown`: https://bitbucket.org/onelson/mezzanine-mdown
 .. _`GnuCash`: http://www.gnucash.org/
 .. _`mezzanine-foundation`: https://github.com/zgohr/mezzanine-foundation
 .. _`Zurb Foundation`: http://foundation.zurb.com/
+.. _`mezzanine-file-collections`: https://github.com/thibault/mezzanine-file-collections
+.. _`mezzanine-wymeditor`: https://github.com/excieve/mezzanine-wymeditor
+.. _`WYMeditor`: http://wymeditor.github.io/wymeditor/
+.. _`mezzanine-meze`: https://github.com/abakan/mezzanine-meze
+.. _`reStructuredText`: http://docutils.sourceforge.net/rst.html
+.. _`Pygments`: http://pygments.org/
+.. _`mezzanine-pageimages`: https://github.com/bcs-de/mezzanine-pageimages
+.. _`mezzanine-protected-pages`: https://github.com/evilchili/mezzanine-protected-pages
 
 
 .. PEOPLE WITH QUOTES

docs/admin-customization.rst

     which lets you specify the URL to your own TinyMCE setup JavaScript
     file.
 
-The default value for the ``RICHTEXT_WIDGET_CLASS`` setting is the string
-``"mezzanine.core.forms.TinyMceWidget"``. The ``TinyMceWidget`` class
-referenced here provides the necessary media files and HTML for
+The default value for the ``RICHTEXT_WIDGET_CLASS`` setting is the
+string ``"mezzanine.core.forms.TinyMceWidget"``. The ``TinyMceWidget``
+class referenced here provides the necessary media files and HTML for
 implementing the TinyMCE editor, and serves as a good reference point
 for implementing your own widget class which would then be specified
 via the ``RICHTEXT_WIDGET_CLASS`` setting.
 
-In addition to ``RICHTEXT_WIDGET_CLASS`` you may need to customize the way
-your content is rendered at the template level. Post processing of the content
-can be achieved through the ``RICHTEXT_FILTER`` setting.
+In addition to ``RICHTEXT_WIDGET_CLASS`` you may need to customize the
+way your content is rendered at the template level. Post processing of
+the content can be achieved through the ``RICHTEXT_FILTERS`` setting,
+which is a sequence of string, each one containing the dotted path to
+a Python function, that will be used as a processing pipeline for the
+content. Think of them like Django's middleware or context processors.
 
-The default behaviour for ``RICHTEXT_FILTER`` is to simply return the parameter
-passed to it.
-
-Say, for example, you had a ``RICHTEXT_WIDGET_CLASS`` that allowed you to write
-your content in a popular wiki syntax. You'd need a way to convert that wiki
-syntax into html right before the content was rendered::
+Say, for example, you had a ``RICHTEXT_WIDGET_CLASS`` that allowed you
+to write your content in a popular wiki syntax such as markdown. You'd
+need a way to convert that wiki syntax into HTML right before the
+content was rendered::
 
     # ... in myproj.filter
     from markdown import markdown
         """
         return markdown(content)
 
-Then by setting ``RICHTEXT_FILTER`` to ``'myproj.filter.markdown_filter'``
-you'd see the converted html content rendered to the template, rather than
-the raw markdown formatting.
+    # ... in myproj.settings
+    RICHTEXT_FILTERS = (
+        "myproj.filter.markdown_filter",
+    )
+
+With the above, you'd now see the converted HTML content rendered to
+the template, rather than the raw markdown formatting.
 
 Media Library Integration
 =========================

docs/content-architecture.rst

     is a child of the current page being viewed
   * ``page.is_current_sibling`` - a boolean for whether the branch page
     is a sibling (has the same parent) of the current page being viewed
+  * ``page.is_current_parent`` - a boolean for whether the branch page
+    is the direct parent of the current page being viewed.
   * ``page.is_current_or_ascendant`` - a boolean for whether the branch
     page is the current page being viewed, or an ascendant (parent,
     grand-parent, etc) of the current page being viewed

docs/deployment.rst

 queried. Note that the Fabric script described earlier includes
 features for deploying templates for cron jobs, which includes the
 job for polling Twitter by default.
+
+As of June 2013, Twitter also requires that all API access is
+authenticated. For this you'll need to configure OAuth credentials for
+your site to access the Twitter API. These settings are configurable
+as Mezzanine settings. See the :doc:`configuration` section for more
+information on these, as well as the `Twitter developer site
+<https://dev.twitter.com/>`_ for info on configuring your OAuth
+credentials.

docs/img/graph-small.png

Old
Old image
New
New image

docs/img/graph.png

Old
Old image
New
New image

docs/inline-editing.rst

 blog post's body. Clicking on the Edit icon will allow the author to update
 the individual piece of content without leaving the page.
 
+In-line editing can be disabled by setting ``INLINE_EDITING_ENABLED`` to
+``False``.
+
 Template Configuration
 ======================
 

docs/search-engine.rst

     models via an abstract model, this is not the case and the result is a
     list of model instances.
 
+    Also of importance is the ``SEARCH_MODEL_CHOICES`` setting mentioned
+    above. When searching across heterogeneous models via an abstract
+    model, the models searched will only be used if they are defined
+    within the ``SEARCH_MODEL_CHOICES`` setting, either explicitly, or
+    implicitly by a model's parent existing in ``SEARCH_MODEL_CHOICES``.
+
 Query Behaviour
 ===============
 

docs/settings.rst

 .. THIS DOCUMENT IS AUTO GENERATED VIA conf.py
 
+``ACCOUNTS_APPROVAL_EMAILS``
+----------------------------
+
+A comma separated list of email addresses that will receive an email notification each time a new account is created that requires approval.
+
+Default: ``''``
+
+``ACCOUNTS_APPROVAL_REQUIRED``
+------------------------------
+
+If ``True``, when users create an account, they will not be enabled by default and a staff member will need to activate their account in the admin interface.
+
+Default: ``False``
+
 ``ACCOUNTS_MIN_PASSWORD_LENGTH``
 --------------------------------
 
 
 Default: ``6``
 
+``ACCOUNTS_NO_USERNAME``
+------------------------
+
+If ``True``, the username field will be excluded from sign up and account update forms.
+
+Default: ``False``
+
 ``ACCOUNTS_PROFILE_FORM_CLASS``
 -------------------------------
 
 
 Default: ``'blog'``
 
-``BLOG_URLS_USE_DATE``
-----------------------
+``BLOG_URLS_DATE_FORMAT``
+-------------------------
 
-If ``True``, URLs for blog post include the month and year. Eg: /blog/yyyy/mm/slug/
+A string containing the value ``year``, ``month``, or ``day``, which controls the granularity of the date portion in the URL for each blog post. Eg: ``year`` will define URLs in the format /blog/yyyy/slug/, while ``day`` will define URLs with the format /blog/yyyy/mm/dd/slug/. An empty string means the URLs will only use the slug, and not contain any portion of the date at all.
 
-Default: ``False``
+Default: ``''``
 
 ``BLOG_USE_FEATURED_IMAGE``
 ---------------------------
 
 Default: ``','``
 
-``FORMS_DISABLE_SEND_FROM_EMAIL_FIELD``
----------------------------------------
-
-If ``True``, emails sent to extra recipients for form submissions won't be sent from an address taken from one of the form's email fields.
-
-Default: ``False``
-
 ``FORMS_EXTRA_FIELDS``
 ----------------------
 
 
 Default: ``()``
 
+``INLINE_EDITING_ENABLED``
+--------------------------
+
+If ``True``, front-end inline editing will be enabled.
+
+Default: ``True``
+
 ``JQUERY_FILENAME``
 -------------------
 
 
 List of inline CSS styles that won't be stripped from ``RichTextField`` instances.
 
-Default: ``()``
+Default: ``('margin-top', 'margin-bottom', 'margin-left', 'margin-right', 'float', 'vertical-align', 'border', 'margin')``
 
 ``RICHTEXT_ALLOWED_TAGS``
 -------------------------
 
 Default: ``('a', 'abbr', 'acronym', 'address', 'area', 'b', 'bdo', 'big', 'blockquote', 'br', 'button', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt', 'em', 'fieldset', 'font', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'li', 'map', 'menu', 'ol', 'optgroup', 'option', 'p', 'pre', 'q', 's', 'samp', 'select', 'small', 'span', 'strike', 'strong', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'tr', 'tt', 'u', 'ul', 'var', 'wbr')``
 
-``RICHTEXT_FILTER``
--------------------
+``RICHTEXT_FILTERS``
+--------------------
 
-Dotted path to the function to call on a ``RichTextField`` value before it is rendered to the template.
+List of dotted paths to functions, called in order, on a ``RichTextField`` value before it is rendered to the template.
 
-Default: ``None``
+Default: ``()``
 
 ``RICHTEXT_FILTER_LEVEL``
 -------------------------
 
 Default: ``'mezzanine/js/tinymce_setup.js'``
 
+``TWITTER_ACCESS_TOKEN_KEY``
+----------------------------
+
+
+
+Default: ``''``
+
+``TWITTER_ACCESS_TOKEN_SECRET``
+-------------------------------
+
+
+
+Default: ``''``
+
+``TWITTER_CONSUMER_KEY``
+------------------------
+
+
+
+Default: ``''``
+
+``TWITTER_CONSUMER_SECRET``
+---------------------------
+
+
+
+Default: ``''``
+
 ``TWITTER_DEFAULT_NUM_TWEETS``
 ------------------------------
 

docs/user-accounts.rst

         "signup_date",
     )
 
+If you don't want to expose the ``username`` field to the user, Mezzanine
+provides the setting ``ACCOUNTS_NO_USERNAME``, which when set to ``True``, will expose the ``email`` field as the sole login for the user.
+
 Account Verification
 ====================
 
 verification link that they must click on, in order to activate their
 account.
 
+Account Approval
+================
 
+You may also wish to manually activate newly created public accounts.
+To enable this, Mezzanine provides the setting
+``ACCOUNTS_APPROVAL_REQUIRED``, which when set to ``True``, will set
+newly created accounts as inactive, requiring a staff member to
+activate each account in the admin interface. A list of email addresses
+can be configured in the admin settings interface, which will then be
+notified by email each time a new account is created and requires
+activation. Users are then sent a notification when their accounts
+are activated by a staff member.
 

mezzanine/__init__.py

 
-__version__ = "1.4.5"
+__version__ = "1.4.16"

mezzanine/accounts/admin.py

+
 from django.contrib import admin
 
 from mezzanine.accounts.models import get_profile_model
+from mezzanine.core.admin import SitePermissionUserAdmin
+from mezzanine.conf import settings
+from mezzanine.utils.email import send_approved_mail, send_verification_mail
 from mezzanine.utils.models import get_user_model
-from mezzanine.core.admin import SitePermissionUserAdmin
 
 
 Profile = get_profile_model()
     extra = 0
 
 
+user_list_display = SitePermissionUserAdmin.list_display
+user_list_display += ("is_active", "date_joined", "last_login")
+
+
 class UserProfileAdmin(SitePermissionUserAdmin):
-    pass
+
+    list_display = user_list_display
+
+    def save_model(self, request, obj, form, change):
+        """
+        If the ``ACCOUNTS_APPROVAL_REQUIRED`` setting is ``True``,
+        send a notification email to the user being saved if their
+        ``active`` status has changed to ``True``.
+        If the ``ACCOUNTS_VERIFICATION_REQUIRED`` setting is ``True``,
+        send a verification email instead.
+        """
+        must_send_verification_mail_after_save = False
+        if change and settings.ACCOUNTS_APPROVAL_REQUIRED:
+            if obj.is_active and not User.objects.get(id=obj.id).is_active:
+                if settings.ACCOUNTS_VERIFICATION_REQUIRED:
+                    # Accounts verification requires an inactive account
+                    obj.is_active = False
+                    # The token generated by send_verification_mail()
+                    # must match the _saved_ User object,
+                    # so postpone send_verification_mail() until later
+                    must_send_verification_mail_after_save = True
+                else:
+                    send_approved_mail(request, obj)
+        super(UserProfileAdmin, self).save_model(request, obj, form, change)
+        if must_send_verification_mail_after_save:
+            user = User.objects.get(id=obj.id)
+            send_verification_mail(request, user, "signup_verify")
+
 
 if Profile:
     UserProfileAdmin.inlines += (ProfileInline,)

mezzanine/accounts/defaults.py

 )
 
 register_setting(
+    name="ACCOUNTS_NO_USERNAME",
+    description=_("If ``True``, the username field will be excluded "
+        "from sign up and account update forms."),
+    editable=False,
+    default=False,
+)
+
+register_setting(
     name="ACCOUNTS_PROFILE_FORM_EXCLUDE_FIELDS",
     description=_("List of fields to exclude from the profile form."),
     editable=False,
     editable=False,
     default=False,
 )
+
+register_setting(
+    name="ACCOUNTS_APPROVAL_REQUIRED",
+    description=_("If ``True``, when users create an account, they will "
+        "not be enabled by default and a staff member will need to activate "
+        "their account in the admin interface."),
+    editable=False,
+    default=False,
+)
+
+register_setting(
+    name="ACCOUNTS_APPROVAL_EMAILS",
+    label=_("Account approval email addresses"),
+    description=_("A comma separated list of email addresses that "
+                  "will receive an email notification each time a "
+                  "new account is created that requires approval."),
+    editable=True,
+    default="",
+)

mezzanine/accounts/forms.py

 from django.contrib.auth import authenticate
 from django.db.models import Q
 from django import forms
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import ugettext as _
 
 from mezzanine.accounts import get_profile_model, get_profile_user_fieldname
 from mezzanine.conf import settings
 from mezzanine.core.forms import Html5Mixin
 from mezzanine.utils.models import get_user_model
-from mezzanine.utils.urls import slugify
+from mezzanine.utils.urls import slugify, unique_slug
 
 
 User = get_user_model()
 
+# If a profile model has been configured with the ``AUTH_PROFILE_MODULE``
+# setting, create a model form for it that will have its fields added to
+# ``ProfileForm``.
+Profile = get_profile_model()
+_exclude_fields = tuple(settings.ACCOUNTS_PROFILE_FORM_EXCLUDE_FIELDS)
+if Profile is not None:
+    class ProfileFieldsForm(forms.ModelForm):
+        class Meta:
+            model = Profile
+            exclude = (get_profile_user_fieldname(),) + _exclude_fields
+
+if settings.ACCOUNTS_NO_USERNAME:
+    _exclude_fields += ("username",)
+    username_label = _("Email address")
+else:
+    username_label = _("Username or email address")
+
 
 class LoginForm(Html5Mixin, forms.Form):
     """
     Fields for login.
     """
-    username = forms.CharField(label=_("Username or email address"))
+    username = forms.CharField(label=username_label)
     password = forms.CharField(label=_("Password"),
                                widget=forms.PasswordInput(render_value=False))
 
         return getattr(self, "_user", None)
 
 
-# If a profile model has been configured with the ``AUTH_PROFILE_MODULE``
-# setting, create a model form for it that will have its fields added to
-# ``ProfileForm``.
-Profile = get_profile_model()
-_exclude_fields = tuple(settings.ACCOUNTS_PROFILE_FORM_EXCLUDE_FIELDS)
-if Profile is not None:
-    class ProfileFieldsForm(forms.ModelForm):
-        class Meta:
-            model = Profile
-            exclude = (get_profile_user_fieldname(),) + _exclude_fields
-
-
 class ProfileForm(Html5Mixin, forms.ModelForm):
     """
     ModelForm for auth.User - used for signup and profile update.
         super(ProfileForm, self).__init__(*args, **kwargs)
         self._signup = self.instance.id is None
         user_fields = User._meta.get_all_field_names()
-        self.fields["username"].help_text = _(
+        try:
+            self.fields["username"].help_text = _(
                         "Only letters, numbers, dashes or underscores please")
+        except KeyError:
+            pass
         for field in self.fields:
             # Make user fields required.
             if field in user_fields:
         if username.lower() != slugify(username).lower():
             raise forms.ValidationError(_("Username can only contain letters, "
                                           "numbers, dashes or underscores."))
+        lookup = {"username__iexact": username}
         try:
-            User.objects.exclude(id=self.instance.id).get(
-                username__iexact=username
-            )
+            User.objects.exclude(id=self.instance.id).get(**lookup)
         except User.DoesNotExist:
             return username
         raise forms.ValidationError(_("This username is already registered"))
         Ensure the email address is not already registered.
         """
         email = self.cleaned_data.get("email")
-        try:
-            User.objects.exclude(id=self.instance.id).get(email=email)
-        except User.DoesNotExist:
+        qs = User.objects.exclude(id=self.instance.id).filter(email=email)
+        if len(qs) == 0:
             return email
         raise forms.ValidationError(_("This email is already registered"))
 
     def save(self, *args, **kwargs):
         """
-        Create the new user using their email address as their username.
+        Create the new user. If no username is supplied (may be hidden
+        via ``ACCOUNTS_PROFILE_FORM_EXCLUDE_FIELDS`` or
+        ``ACCOUNTS_NO_USERNAME``), we generate a unique username, so
+        that if profile pages are enabled, we still have something to
+        use as the profile's slug.
         """
+
+        kwargs["commit"] = False
         user = super(ProfileForm, self).save(*args, **kwargs)
+        try:
+            self.cleaned_data["username"]
+        except KeyError:
+            if not self.instance.username:
+                username = "%(first_name)s %(last_name)s" % self.cleaned_data
+                if not username.strip():
+                    username = self.cleaned_data["email"].split("@")[0]
+                qs = User.objects.exclude(id=self.instance.id)
+                user.username = unique_slug(qs, "username", slugify(username))
         password = self.cleaned_data.get("password1")
         if password:
             user.set_password(password)
-            user.save()
+        user.save()
 
         # Save profile model.
         if self._has_profile:
-            profile = user.get_profile()
+            try:
+                profile = user.get_profile()
+            except Profile.DoesNotExist:
+                profile = Profile(user=user)
             profile_fields_form = self.get_profile_fields_form()
             profile_fields_form(self.data, self.files, instance=profile).save()
 
         if self._signup:
             settings.use_editable()
-            if settings.ACCOUNTS_VERIFICATION_REQUIRED:
+            if (settings.ACCOUNTS_VERIFICATION_REQUIRED or
+                settings.ACCOUNTS_APPROVAL_REQUIRED):
                 user.is_active = False
                 user.save()
             else:
     token for authenticating to change their password.
     """
 
-    username = forms.CharField(label=_("Username or email address"))
+    username = forms.CharField(label=username_label)
 
     def clean(self):
         username = self.cleaned_data.get("username")

mezzanine/accounts/locale/ar/LC_MESSAGES/django.mo

Binary file modified.

mezzanine/accounts/locale/ar/LC_MESSAGES/django.po

 # SOME DESCRIPTIVE TITLE.
 # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
 # This file is distributed under the same license as the PACKAGE package.
-#
+# 
 # Translators:
 # Ahmad Khayyat <akhayyat@gmail.com>, 2012-2013
 msgid ""
 msgstr ""
 "Project-Id-Version: Mezzanine\n"
-"Report-Msgid-Bugs-To: \n"
+"Report-Msgid-Bugs-To: https://github.com/stephenmcd/mezzanine/issues\n"
 "POT-Creation-Date: 2013-10-05 07:21-0430\n"
 "PO-Revision-Date: 2013-07-02 07:10+0000\n"
 "Last-Translator: Ahmad Khayyat <akhayyat@gmail.com>\n"
-"Language-Team: Arabic (http://www.transifex.com/projects/p/mezzanine/"
-"language/ar/)\n"
-"Language: ar\n"
+"Language-Team: Arabic (http://www.transifex.com/projects/p/mezzanine/language/ar/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
-"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
+"Language: ar\n"
+"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
 
 #: defaults.py:20
 msgid "Minimum length for passwords"
 
 #: defaults.py:51
 msgid ""
-"If ``True``, when users create an account, they will be sent an email with a "
-"verification link, which they must click to enable their account."
+"If ``True``, when users create an account, they will be sent an email with a"
+" verification link, which they must click to enable their account."
 msgstr ""
 
 #: forms.py:21 forms.py:190
 #: views.py:57
 msgid ""
 "A verification email has been sent with a link for activating your account."
-msgstr ""
-"تم إرسال رسالة إلكترونية تحوي رابط تنشيط حسابك إلى بريدك الإلكتروني للتأكد "
-"من صحته."
+msgstr "تم إرسال رسالة إلكترونية تحوي رابط تنشيط حسابك إلى بريدك الإلكتروني للتأكد من صحته."
 
 #: views.py:61 views.py:80
 msgid "Successfully signed up"
 #: templates/accounts/account_login.html:11
 #, python-format
 msgid ""
-"If you don't have an account you can <a href=\"%(signup_url)s?next=%(next)s"
-"\">sign up</a> for one now."
-msgstr ""
-"إذا لم يكن لديك حساب، يمكنك <a href=\"%(signup_url)s?next=%(next)s\">إنشاء "
-"حساب جديد</a> الآن."
+"If you don't have an account you can <a "
+"href=\"%(signup_url)s?next=%(next)s\">sign up</a> for one now."
+msgstr "إذا لم يكن لديك حساب، يمكنك <a href=\"%(signup_url)s?next=%(next)s\">إنشاء حساب جديد</a> الآن."
 
 #: templates/accounts/account_login.html:14
 #, python-format
 msgid ""
-"<p>You can also <a href=\"%(password_reset_url)s?next=%(profile_update_url)s"
-"\">reset your password</a> if you've forgotten it.</p>"
-msgstr ""
-"<p>يمكنك كذلك <a href=\"%(password_reset_url)s?next=%(profile_update_url)s"
-"\">إعادة ضبط كلمة السر الخاصة بك</a> إذا كنت قد نسيتها.</p>"
+"<p>You can also <a "
+"href=\"%(password_reset_url)s?next=%(profile_update_url)s\">reset your "
+"password</a> if you've forgotten it.</p>"
+msgstr "<p>يمكنك كذلك <a href=\"%(password_reset_url)s?next=%(profile_update_url)s\">إعادة ضبط كلمة السر الخاصة بك</a> إذا كنت قد نسيتها.</p>"
 
 #: templates/accounts/account_password_reset.html:6
 msgid ""
-"Enter your username or email address and you'll receive an email with a link "
-"you need to click, in order to log in and change your password."
-msgstr ""
-"أدخل اسم المستخدم أو عنوان البريد الإلكتروني الخاصين بك، وستتلقى رسالة "
-"إلكترونية تحوي رابطاً يمكنك من إعادة ضبط كلمة السر الخاصة بك."
+"Enter your username or email address and you'll receive an email with a link"
+" you need to click, in order to log in and change your password."
+msgstr "أدخل اسم المستخدم أو عنوان البريد الإلكتروني الخاصين بك، وستتلقى رسالة إلكترونية تحوي رابطاً يمكنك من إعادة ضبط كلمة السر الخاصة بك."
 
 #: templates/accounts/account_profile.html:17
 #: templates/accounts/includes/user_panel.html:9
 
 #: templates/accounts/account_signup.html:7
 msgid ""
-"You're already logged in. If you'd like to create a new account, you'll need "
-"to log out first."
-msgstr ""
-"لقد قمت بتسجيل دخولك مسبقاً. إذا كنت تريد إنشاء حساب جديد، لا بد أن تقوم "
-"بتسجيل الخروج أولاً."
+"You're already logged in. If you'd like to create a new account, you'll need"
+" to log out first."
+msgstr "لقد قمت بتسجيل دخولك مسبقاً. إذا كنت تريد إنشاء حساب جديد، لا بد أن تقوم بتسجيل الخروج أولاً."
 
 #: templates/accounts/account_signup.html:11
 msgid ""
 "After signing up, you'll receive an email with a link you need to click, in "
 "order to activate your account."
-msgstr ""
-"بعد إنشاء حساب جديد، ستتلقى رسالة إلكترونية تحوي رابطاً يمكنك من تنشيط حسابك."
+msgstr "بعد إنشاء حساب جديد، ستتلقى رسالة إلكترونية تحوي رابطاً يمكنك من تنشيط حسابك."
 
 #: templates/accounts/includes/user_panel.html:4
 msgid "Logged in as: "

mezzanine/accounts/locale/cs/LC_MESSAGES/django.mo

Binary file modified.

mezzanine/accounts/locale/cs/LC_MESSAGES/django.po

 msgstr ""
 "Project-Id-Version: Mezzanine\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-10-05 07:21-0430\n"
-"PO-Revision-Date: 2012-10-14 21:42+0000\n"
-"Last-Translator: Sebastián Ramírez Magrí <sebasmagri@gmail.com>\n"
+"POT-Creation-Date: 2013-04-29 09:05+0200\n"
+"PO-Revision-Date: 2013-04-29 09:05+0100\n"
+"Last-Translator: Petr Papoušek <ppapousek@gmail.com>\n"
 "Language-Team: Czech (http://www.transifex.com/projects/p/mezzanine/language/"
 "cs/)\n"
 "Language: cs\n"
 "Dotted package path and class name of profile form to use for users signing "
 "up and updating their profile, when ``mezzanine.accounts`` is installed."
 msgstr ""
+"Tečkami oddělená cesta k balíčku a názvu třídy formuláře pro profil, který "
+"se má použít, když se uživatelé registrují, nebo aktualizují svůj profil, "
+"když je nainstalovaný balíček ``mezzanine.accounts``."
 
 #: defaults.py:43
 msgid "If ``True``, users will have their own public profile pages."
 msgstr ""
-"Je-li tato hodnota nastavena na ``True``, uživatelé budou mít vlastí "
+"Je-li tato hodnota nastavena na ``True``, uživatelé budou mít vlastní "
 "profilové stránky. "
 
 #: defaults.py:51
 "bude jim odeslán email s ověřovacím odkazem, na který musejí kliknout pro "
 "odemčení účtu."
 
+#: defaults.py:60
+msgid ""
+"If ``True``, when users create an account, they will not be enabled by "
+"default and a staff member will need to activate their account in the admin "
+"interface."
+msgstr ""
+"Je-li tato hodnota nastavena na ``True``,  když si uživatelé vytvoří účet, "
+"nebude aktivní a bude vyžadovat schválení personálem v administračním "
+"rozhraní."
+
+#: defaults.py:69
+msgid "Account approval email addresses"
+msgstr "Emailová adresa schvalování účtů"
+
+#: defaults.py:70
+msgid ""
+"A comma separated list of email addresses that will receive an email "
+"notification each time a new account is created that requires approval."
+msgstr ""
+"Čárkami oddělený seznam emailových adres, na které bude odeslán email při "
+"vzniku uživatelského účtu vyžadujícího schválení."
+
 #: forms.py:21 forms.py:190
 msgid "Username or email address"
-msgstr ""
+msgstr "Uživatelské jméno nebo emailová adresa"
 
 #: forms.py:22 forms.py:66
 msgid "Password"
 
 #: forms.py:35
 msgid "Invalid username/email and password"
-msgstr ""
+msgstr "Neplatná kombinace uživatelského hesla nebo emailu a hesla"
 
 #: forms.py:37