Woost changelog



Requires cocktail/absinthe.


  • Fixed the version specifier for the dependency on cocktail, to allow variations in microversions.


The main feature of this release is the addition of the blocks extension.

Requires cocktail/absinthe.


  • Fixed the version specifier for the dependency on cocktail, to allow variations in microversions.


The main feature of this release is the support for hosting multiple subsites on a single project/installation.

Requires cocktail/absinthe.


  • Fixed the version specifier for the dependency on cocktail, to allow variations in microversions.


The main feature of this release is the support for synchronizing content across different installations of the same website.

Requires cocktail/baileys.

  • Removed the woost.models.FileListing block. Use woost.models.PublishableListing instead. A migration step has been added to convert existing obsolete blocks to the new model.

  • Removed the woost.models.YouTubeBlock and woost.models.VimeoBlock blocks (along with the image renderers for both). Both block types should be replaced with woost.models.VideoBlock. A migration step has been added to convert existing obsolete blocks to the new model.

  • Support for synchronizing content across different installations of the same website. Introduces the following changes:

    • Added the woost.models.SiteInstallation model
    • Added the woost.application.Application.installation_id property
    • Added the woost.models.Item.global_id member
    • Added the woost.models.Item.synchronizable member
    • Added the cocktail.schema.Member.synchronizable property
  • Added the woost.application.Application.installation_color property. This can helps in telling different installations of a site appart at a glance. Also, many styles in the backoffice have been changed to have a more subtle and color neutral appearence, so they can work better with the changing color in the heading.

  • Redesigned the type selection menu in the backoffice.


  • Fixed the version specifier for the dependency on cocktail, to allow variations in microversions.



The main changes in this release are the adoption of the blocks extension in the core, the move to the new cache infrastructure provided by the cocktail.caching package, a new system for composing and resolving URLs and dropping support for all template systems except CML.

Requires cocktail/cointreau.

  • Merged the blocks extension into the core. The extension can still be imported, but it is deprecated and has no effect.

  • woost.models.StandardPage and woost.extensions.blocks.blockspage.BlocksPage become deprecated aliases for a new woost.models.Page model.

  • Use the cache system introduced by cocktail/cointreau.

    • No longer uses Beaker for caching (it is still used to deal with user sessions)
    • Added a user action in the backoffice to manually invalidate the cache
    • Removed the woost.models.CachingPolicy.content_last_update_expression member
    • Adde the woost.models.CachingPolicy.cache_tags_expression member
    • Cache is now usable even when browsing as an authenticated user:
      • User roles are added as a caching key
      • The active user indicator in the frontend is now added using javascript, so it is not included in the cached content
  • Removed the woost.models.Action class. The woost.models.Change.action member is now expressed using strings instead.

  • Removed the woost.models.Item.owner member, to avoid conflicts when caching content for authenticated users.

  • Removed the support for document drafts, as it didn't mix well with pages based on blocks.

  • Removed the workflow extension, since it didn't work well with block based pages.

  • Removed the woost.models.Document.attachments member, since using a listing block instead will be usually preferable.

  • Removed support for per page inclusion of linked scripts and style sheets. This was seldom used and page templates can cover most cases while providing better control.

    • Removed the woost.models.Document.page_resources member
    • Removed the woost.models.Document.branch_resources member
    • Removed the woost.models.Publishable.inherit_resources member
  • Removed support for multiple template engines (buffet) in favor of CML templates.

    • Most websites were already using CML templates
    • Having a single template language simplifies the implementation of the standard templates
    • Relying on cocktail.html gives us better integration with the cocktail.caching package (f. eg. in regards to cache entry tagging)
  • Changed the URL composition / resolution system.

    • Removed the woost.models.PublicationSchema model and its subclasses
    • Added the woost.urlresolver module
    • Added the woost.application.Application.url_resolver property
    • The new system should be more efficient (no need to load resolvers from the database) and more friendly to unit tests
  • Added a woost.models.initialization.SiteInitializer class that replaces the old woost.models.initialization.init_site() function. The new class based approach is much more flexible and structured.

  • Added the woost.models.Block.initialization member.

  • Improvements to the googleanalytics extension.

    • Added support for the universal API
    • Added the woost.extensions.googleanalytics.utils.add_event() function
  • Added the woost.models.Publishable.is_internal_content() method.


Fixed the version specifier for the dependency on cocktail, to allow variations in microversions.


  • The pdf extension served files using the application/x-pdf extension; this has been corrected to application/pdf. Some user agents (notably, some versions of the Android download manager) couldn't deal with the first form. 



The main features for this release are support for translation inheritance and user interface improvements in the backoffice.

Requires cocktail/damassine.

  • User interface improvements in the backoffice.

    • Reorganized the controls in listing views, arranging the toolbar in a single row
    • Moved the references view to a specific view (loading it outright from the edit/details view could have a heavy impact on objects with lots of references)
    • Removed the action bar below the edit view, since tabs make it mostly unnecessary
    • Redesigned the visible translations selector in backoffice listings
    • Redesigned the visible columns selector in backoffice listings
    • Show the frequent views bar on all views
    • Improved keyboard navigation
    • Autofocus the first control of the login form and the edit view
  • Removed the Show details user action.

  • Removed the Print user action.

  • Changed the pattern for the translation keys of user actions and their shortcuts. The new patterns are woost.action.ACTION and woost.action.ACTION.shortcut, respectively.

  • Replaced all backoffice dropdown panels with cocktail.html.DropdownPanel.

  • Support for translation inheritance and websites with a large number of locales (100+)

    • Added the woost.models.Configuration.fallback_languages member
    • Redesigned the translations selector in the edit view
    • Added a selector to toggle the visible translations in the blocks editor
    • Show values inherited from other translations in backoffice listings
  • Added the woost.models.TextBlock.heading_icon member.

  • Added the annotations extension.

  • Added the notices extension.


  • Fixed the version specifier for the dependency on cocktail, to allow variations in microversions.


  • The pdf extension served files using the application/x-pdf extension. Corrected to application/pdf. Some user agents (notably, some versions of the Android download manager) couldn't deal with the first form. 



The main change of this release is the overhaul of the permissions system.

Requires cocktail/damassine.

  • Overhaul of the content permissions system.

    The modeling and behavior of the woost.models.ContentPermission class has been altered, so this change affects all permissions for creating, modifying, reading and deleting objects.

    • The woost.models.ContentPermission.matching_items member has been removed
    • The class doesn't use UserCollection / UserFilter anymore
    • The new implementation uses two new members (woost.models.ContentPermission.content_type and woost.models.ContentPermission.content_expression) which are used to obtain a cocktail.persistence.Query object encompassing all the objects affected by the permission

    The changes provide a big performance boost, while also solving many long standing bugs when creating / editing permissions from the backoffice.

  • The language member of woost.models.EmailTemplate has been renamed to language_expression, to work around a bug in the backoffice.

  • Changed the default value of woost.models.rendering.Fill.preserve_vertical_images to False.

  • woost.controllers.firstchildredirectioncontroller.FirstChildRedirectionController has been deprecated.

  • Added the woost.models.rendering.AutoCrop image effect.

  • Allow images to be upscaled, using the new upscale option of the woost.models.rendering.Thumbnail and woost.models.rendering.Fill image effects.

  • staticsite extension: added Python expressions to the exporters to enable the postprocessing of the exported static files.

  • Enable the Show published action for blocks.

  • Added the woost.models.Document.redirection_mode member, to choose between several redirection behaviors (temporary, permanent or using javascript).

  • Added the woost.models.TextBlock.image_footnotes_visible member, to determine if text blocks should display image footnotes.

  • Added the woost.models.utils.restore_deleted_item() function, to simplify the recovery of deleted objects.

  • Added support for including file extensions in the woost.urlresolver.IdURLScheme URL scheme.

  • Added an option to have blocks based on a definition list wrap their entries using a <div> element. While this is technically invalid HTML, browsers render it just fine and it simplifies styling enormously.

  • Improvements to the script.

    • Added the module, to be able to retroactively modify the symbols exported by the script of each project
    • Added the iter_text(), get(), req(), grep(), hl(), replace(), show() and edit() functions

    Note that existing projects must regenerate their file, using the template provided in woost/scripts/project_skeleton/scripts/

  • Disable URL processing in TinyMCE; preserve URLs as editors enter them.


  • Fixed the version specifier for the dependency on cocktail, to allow variations in microversions.


  • The pdf extension served files using the application/x-pdf extension. Corrected to application/pdf. Some user agents (notably, some versions of the Android download manager) couldn't deal with the first form. 



This branch introduces changes to the publication system, changing the way objects specify which languages they should be published in, and replacing the restrictedaccess extension with equivalent functionality in the core.

  • Replaced woost.models.Publishable.translation_enabled member with the new woost.models.Publishable.enabled_translations collection.

    Using a collection of published languages, instead of a translated boolean member solves issues derived from the translation inheritance system: for example, in order to state that a derived language shouldn't be published it was necessary to add a translation for that language, which in many cases would be undesirable.

  • The restrictedaccess extension is now deprecated, as its functionality has been merged into the core.

    • Added the woost.models.AccessLevel model
    • Added the woost.models.Publishable.access_level member
    • Added the woost.models.Role.access_levels member
  • Try to use a series of languages when describing objects in the backoffice.

    • Added the woost.models.Configuration.backoffice_language_chain member
    • Added the woost.models.User.backoffice_language_chain member
  • Added the variables extension. The extension makes it possible to apply site wide text substitutions on the produced HTML output.

  • Restored the Changelog action in the backoffice, fixing several issues.

  • Added the woost.models.Change.is_explicit_change member, to differentiate user initiated changes from side effects.

  • staticsite extension: added the woost.extensions.staticsite.staticsitedestination.AmazonS3Destination, to support exporting websites to an Amazon S3 bucket

  • Sort languages alphabetically in the backoffice.

  • staticsite extension: don't remove the directory generated by woost.extensions.staticsite.staticsitesnapshoter.WgetSnapShoter. Preserving the directory can aid in debugging, and it works around certain bugs.


  • Fixed the version specifier for the dependency on cocktail, to allow variations in microversions.


  • The pdf extension served files using the application/x-pdf extension. Corrected to application/pdf. Some user agents (notably, some versions of the Android download manager) couldn't deal with the first form. 



This release introduces changes to full text searches, further improvements to the permissions system and an assortment of fixes and improvements.

Requires cocktail/feni.

  • Changes and improvements to permissions.

    • woost.models.Permission.match() now receives a user parameter indicating the user that the permission is being validated for
    • It is now possible to translate a woost.models.ContentPermission object containing a content expression that raises an exception
    • Added the woost.models.ContentPermission.subject_description member, to make it possible to override the description of content permissions
  • Changes and improvements for text searches.

    • Adapted to the changes in the full text search system introduced by cocktail/feni
    • Use the cocktail.schema.HTML member type where appropiate, to improve full text indexing
    • Flag several members as not searchable
    • Added the function
    • Include blocks in the body of searchable text of their containers
  • Added the woost.models.Item.get_representative_image() method, to make it easier to have an object use another object as its image.

  • Added the cocktail.schema.Schema.skip_listing property, to indicate that a model is a singleton and that selecting it on the backoffice menu should edit its single instance instead. Basically used to speed up the access to the woost.models.Configuration object in the backoffice.

  • Added woost.views.EventsCalendar as an option for the appearence of woost.models.EventListing blocks, to show events in a month calendar layout.


  • Fixed the version specifier for the dependency on cocktail, to allow variations in microversions.


  • The pdf extension served files using the application/x-pdf extension. Corrected to application/pdf. Some user agents (notably, some versions of the Android download manager) couldn't deal with the first form. 



This release updates the codebase to match the changes in schema validations introduced by cocktail/gin.

Requires cocktail/gin.

  • Make woost.models.Publishable.parent an indexed member. A migration step has been added to effect this change.

  • Make the generation of block views more flexible.

    • Added the woost.models.Block.get_view_class() method
    • woost.models.blockutils.create_block_views() and woost.models.Block.create_view() now accept arbitrary keyword arguments
  • Changed the signature of the woost.views.ActionBar.create_action_button() method. It now receives a third parameter with the context for the action.

  • woost.models.Publishable.websites and woost.models.Website.specific_content now use sets instead of lists. A migration step has been added to effect this change.

  • Added the woost.controllers.fileuploader.FileUploader class, as a more flexible alternative to woost.controllers.uploadform.UploadForm. The classes provide (mostly) equivalent functionality, but since FileUploader is independant of any controller, it can be used in more situations (f. eg. in cocktail.schema.Expansion adaptation rules).

  • Added a Duplicate action to the backoffice.

  • Added the newsletters extension, to simplify the composition of HTML newsletters that can be sent as e-mail messages.

  • Added a verbose parameter to the woost.models.rebuild_manifest() function

  • Improvements to representative images.

    • Added the woost.models.Item.resolve_representative_image() method
    • woost.models.rendering.ImageFactory.can_render() now takes into account representative images
  • Added the woost.views.viewfactory.ViewFacotry.handler_for() method, to provide more convenient syntax for registering functions as handlers in a view factory

  • woost.models.Template.identifier is no longer a unique member. A migration step has been added to effect this change.

  • Added the woost.controllers.autocompletecontroller.AutocompleteController class. It is a subclass of the homonimous controller in cocktail, adding permission and publication state checks.

  • Added the forms extension, which allows editors to design their own forms.

  • New installer.

  • Added the identity extension, to allow users to authenticate using external identity providers, such as Google and Facebook.


  • Fixed the version specifier for the dependency on cocktail, to allow variations in microversions.


  • The pdf extension served files using the application/x-pdf extension. Corrected to application/pdf. Some user agents (notably, some versions of the Android download manager) couldn't deal with the first form. 



The focus of this release is on improvements to the backoffice user interface.

Requires cocktail/horilka.

  • Added support for contextual menus in the backoffice.

    • woost.views.ItemDisplay replaces woost.views.ItemLabel as the default view for elements in the backoffice
    • Replaced woost.models.Item.backoffice_heading_view with woost.models.Item.backoffice_card_view
    • All BackOffice...HeadingView classes are renamed to ...Card
  • Suport read only fields in backoffice edit views.

    • The cocktail.schema.Member.editable property is now defined by cocktail.schema. Instead of boolean values, now it must be set to any of the following constants:
      • cocktail.schema.EDITABLE
      • cocktail.schema.NOT_EDITABLE
      • cocktail.schema.READ_ONLY
    • woost.controllers.backoffice.editcontroller.EditController doesn't require modification rights anymore
    • Added a woost.controllers.backoffice.editstack.EditNode.get_member_edit_mode() method that replaces the old woost.controllers.backoffice.editstack.EditNode.should_exclude_member(), which is no longer available. The old method returned a boolean, the new one should return one of the three constants enumerated above.
    • Added the woost.controllers.backoffice.editstack.EditNode.verbose_member_mode property, to aid in debugging why a particular member ends up being editable / not editable / read only
  • Improvements to the backoffice actions system.

    • Action bars will now contain all actions that can be potentially applied to the current context, including actions that only apply to a subset of the listed items. Actions that are not applicable to the active selection will be disabled or hidden. Previously, only actions that could apply to all the elements in the listing were included.
    • The action context identifiers ending with the _extra suffix are gone; in their stead, the following elements have been added:
      • woost.controllers.backoffice.useractions.UserAction.show_as_primary_action
      • woost.controllers.backoffice.useractions.UserAction.is_primary()
    • Removed functions to add context for user actions:
      • woost.controllers.backoffice.useractions.add_view_action_context()
      • woost.controllers.backoffice.useractions.get_view_actions_context()
    • Added the woost.controllers.useractions.UserAction.unregister() method
    • Added the woost.controllers.useractions.UserAction.unregister() method
    • Added the woost.controllers.useractions.UserAction.hidden_when_disabled property
  • The woost.models.blockutils.type_is_block_container() changes its behavior to only consider the indicated type. The previous behavior (include both the given type and its descendants) is now available under the new woost.models.blockutils.schema_tree_has_block_container() function.

  • Improvements to the changelog view.

    • Added the woost.views.ChangeLog view, which replaces woost.views.ChangelogTable
    • Group the listing by date
    • Group similar actions
    • Improved the indexing of woost.models.ChangeSet and woost.models.Change, for a big performance boost. A migration step has been added to effect this change.
    • Added the woost.models.ChangeSetHasChangeFilter user filter, which replaces all previous history related user filters
  • Improvements to woost.controllers.uploadform.UploadForm to ease the customization of the upload fields generated by the form.

    • Part of the woost.controllers.uploadform.UploadForm.upload_options dictionary is moved to a new woost.controllers.uploadform.UploadForm.default_upload_options property
    • Added the woost.controllers.uploadform.UploadForm.get_upload_options() method
  • New notifications API.

    • Added the woost.controllers.notifications.Notification class
    • The old API is still usable. Only users who extended or customized the behavior or appearence of cocktail.html.NotificationBox should be affected by the changes.
  • Changes to the locations extension.

    • Added the woost.extensions.locations.extension.countryreference.CountryReference class, as a convenience to simplify the declaration of references to countries
    • Added the woost.extensions.locations.LocationSelector view
    • The woost.extensions.locations.location.Location.by_code() and woost.extensions.locations.location.Location.by_path() methods were problematic and have been deprecated in favor of the new woost.extensions.locations.location.Location.by_abs_path() method. The problem with the old methods is that using relative paths as a search criteria could lead to a single path producing two or more matching elements.
  • Support for tabbed listings in the backoffice.

    • Added the woost.models.Item.backoffice_listing_tabs() method
    • Added the woost.models.Item.backoffice_listing_default_tab() method
  • Added properties that make it possible/easier to have different display / edit controls / search controls for members in the backoffice.

    • Added the cocktail.schema.Member.backoffice_display property, which overrides cocktail.schema.Member.display in the backoffice
    • Added the cocktail.schema.Member.backoffice_edit_control property, which overrides cocktail.schema.Member.edit_control in the backoffice
    • Added the cocktail.schema.Member.backoffice_search_control property, which overrides cocktail.schema.Member.search_control in the backoffice
  • The backoffice will now hide object icons in many cases, only displaying them when it feels they will add valuable information to the listing (ie. type distinction on heterogeneous listings or representative images).

    Models can explicitly request that their icons be always displayed using the new woost.models.Item.icon_conveys_information property.

  • Added the woost.controllers.backoffice.editstack.StackNode.push_to_stack() method

  • Improvements to the Export to MS Excel action in the backoffice.

    • Added the cocktail.schema.Member.included_in_backoffice_msexcel_export property, to make it easier to exclusde certain columns from the produced spreadsheet
    • Added the cocktail.schema.Member.backoffice_msexcel_exporter property, to make it possible to alter the composition, format and style on a per column basis
  • Add support to woost.views.ItemCollectionEditor for the cocktail.html.grouping API, to make it possible to edit lists that require non arbitrary sorting and/or row grouping / hierarchies.

  • Offer more options to determine which translations should be added / enabled when creating / editing an object in the backoffice.

    • Added the woost.models.User.backoffice_visible_translations member, to toggle translations shown on the backoffice on a per user basis
    • The new woost.controllers.cmscontroller.CMSController.choosing_visible_translations event makes it possible to alter the list of translations to add / enable programmatically
  • Added the woost.models.utils.rebase_id() function, to regenerate the unique identifiers all the site objects, starting from the given number.

    Use case: recreating an existing website (ie. to remake it in a newer version) and forgetting to pass the --base-id parameter to the installer.

  • Added the woost.views.PublishableCollage view and made it an appearence option for woost.views.PublishableListing.

  • Added the woost.models.utils.show_translation_coverage() function.

  • Added the woost.models.importurl module, to import remote URLs as publishable objects of the site.

  • Added the woost.models.URI.image member.

  • Added an API to import/export objects using JSON serialization.

    • Added the woost.models.objectio module, to simplify the copying of objects between websites
    • Added convenience methods in woost.models.utils:
      • woost.models.utils.copy_to_clipboard()
      • woost.models.utils.paste_from_clipboard()
      • woost.models.utils.export_json()
      • woost.models.utils.import_json()
    • Added a dependency to the clipboard module
  • Added a dependency to the enum34 package, to be able to declare enumerations using the syntax provided by Python 3.

  • Hide the woost.models.Item.creation_time column by default on backoffice listings.

  • Flag subclasses of woost.models.Extension as not instantiable.


  • Fixed the version specifier for the dependency on cocktail, to allow variations in microversions.


  • The pdf extension served files using the application/x-pdf extension. Corrected to application/pdf. Some user agents (notably, some versions of the Android download manager) couldn't deal with the first form. 



The main features of this branch are the upgrade of jQuery, an overhaul of the googleanalytics extension and new APIs for accessing request context.

Requires cocktail/izarra.

  • Upgraded jQuery to 1.11.3.

  • Changes to the googleanalytics extension.

    • Removed support for the old analytics API; assume all properties are using the universal API.
    • Added the client side object
    • Added the woost.extensions.googleanalytics.utils.escape_ga_string() function
    • Added the woost.extensions.googleanalytics.utils.get_ga_value() function
    • Added the woost.extensions.googleanalytics.utils.get_ga_custom_values() function
    • Removed the woost.extensions.googleanalytics.utils.add_event() function. Instead, the following properties have been added to cocktail.html.Element:
      • cocktail.html.Element.ga_event_category
      • cocktail.html.Element.ga_event_action
      • cocktail.html.Element.ga_event_label
      • cocktail.html.Element.ga_event_value
      • cocktail.html.Element.ga_event_source
      • cocktail.html.Element.ga_event_env
      • cocktail.html.Element.ga_event_overrides
      • New system for defining custom dimensions and metrics. A new woost.extensions.googleanalytics.customdefinition.GoogleAnalyticsCustomDefinition model has been introduced to represent each of the custom dimensions and metrics exported by the website (see also the woost.models.Website.google_analytics_custom_definitions member). A migration step has been added to declare the standard dimensions generated by Woost. Site specific dimensions that were declared using the woost.extensions.googleanalytics.GoogleAnalyticsExtension.declaring_tracker event will need to be declared by hand.
      • The CMS now generates Google Analytics events by default for most links and buttons
  • Replace the image gallery in woost.views.ItemCard with a player or control specific to the presented object (for example, a video player for a YouTube video, a download link for a ZIP file, etc).

    • Added the woost.views.viewfactory.item_card_view_factory object
    • Removed item_image_gallery and get_item_images() in woost.views.ItemCard
  • Removed the old controllers that implemented webservices to create / read / modify / delete content. They had been out of use for a long while.

  • New APIs for accessing contextual properties:

    • woost.application.Application.publishable: provides access to the publishable object for the current request. Previously accessed through the publishable key of cocktail.controllers.context.
    • woost.application.Application.original_publishable: provides access to the publishable object that was requested in the current request and replaced because of an error. For example, in a 403 error, app.publishable will point to the access denied error page while app.original_publishable will point to the document that had been requested. Previously accessed through the original_publishable key of cocktail.controllers.context.
    • woost.application.Application.user: provides access to the current user. Previously accessed through woost.models.get_current_user().
    • woost.application.Application.error: if a request for a publishable object triggers an error, this will contain a reference to the raised exception. Had no previous equivalent.

    All the previous APIs still work, but they may issue deprecation warnings.

  • Added a mechanism to fake the active navigation point in the menu.

    • Added the woost.application.Application.navigation_point property.
    • Added the woost.controllers.navigationpoint.get_navigation_point() generic method
  • Added the woost.views.Breadcrumbs view.

  • Support to customize meta tags, either globally, per website or per document:

    • Added the woost.models.metatags.MetaTags member type
    • Added the woost.models.Configuration.meta_tags member
    • Added the woost.models.Website.meta_tags member
    • Added the woost.models.Document.meta_tags member
  • Add a default error page.

    • Added the woost.models.DebugPermission permission type
    • Added the woost.models.Website.technical_contact_email member
    • Added the woost.views.Traceback view
    • Added the woost.application.Application.traceback property
    • Added the woost.application.Application.traceback_link_style property


  • Fixed the version specifier for the dependency on cocktail, to allow variations in microversions.


  • The pdf extension served files using the application/x-pdf extension. Corrected to application/pdf. Some user agents (notably, some versions of the Android download manager) couldn't deal with the first form. 



  • forms extension: make it possible to override the translation of form agreements.



The main changes in this release concern the standard page templates.

Requires cocktail/izarra.

  • Changes to the standard page templates.

    • Removed support for HTML4
    • Removed the "incomplete translation" notice (hadn't worked - or been in use - for a long while)
    • Introduced a main tag
    • Renamed multiple elements
      • header -> site_header
      • title_label -> site_title
      • title_label_text -> site_title_text
      • site_home_link -> home_link
      • navigation -> site_navigation
      • navigation_heading -> site_navigation_heading
      • main -> main_article (but see the distinction between main_article and main)
      • content_title_label -> main_heading
      • content -> main_content
      • block_content -> main_blocks
      • footer -> site_footer
      • toolbar -> cms_edit_panel
    • Added or modified several methods:
      • woost.views.StandardView.get_logo() becomes woost.views.StandardView.get_site_logo()
      • woost.views.BaseView.get_keywords() becomes woost.views.BaseView.get_page_keywords()
      • Added woost.views.BaseView.get_site_title()
      • Added woost.views.BaseView.get_main_title()
      • Modified woost.views.BaseView.get_page_title() so that it combines woost.views.BaseView.get_site_title() and woost.views.BaseView.get_main_title()
      • Added Added woost.views.StandardView.get_main_heading_title()
      • Added woost.views.BaseView.get_page_description()
      • Added woost.views.BaseView.get_page_icon()
  • Added the navigation ARIA role to the woost.views.Breadcrumbs view.



  • The pdf extension served files using the application/x-pdf extension. Corrected to application/pdf. Some user agents (notably, some versions of the Android download manager) couldn't deal with the first form. 



  • forms extension: make it possible to override the translation of form agreements.



Requires cocktail/komovica.

  • Adapted to the changes to static resources in cocktail/komovica.

    • Woost static resources moved from /resources to /resources/woost
    • Site specific static resources moved from /XYZ_resources to /resources/XYZ
    • Use resource repository URL schemes everywhere (ie. woost://)
    • Added the woost.application.Application.add_resources_repository() method
    • Added the woost.controllers.cmsresourcescontroller.CMSResourcesController class
  • Use woost.views.Link in woost.views.PublishableListing classes.

    • Removed the woost.views.PublishableListing.get_item_uri() method
    • Added the woost.views.PublishableListing.create_publishable_link() method
  • Removed the workaround for IE to support column layouts in text blocks.

  • Added the woost.models.Document.custom_document_title member.

  • Added the woost.views.BlockList.get_blocks() method

  • Added the woost.views.ExtractNewsListing view.

  • Use woost.views.Link in woost.views.ThumbnailLink.

  • Added the woost.views.Link.force_download property.

  • Added the attributes extension.

  • Added the Google Tag Manager extension.

  • Support reading the values for custom Google Analytics dimensions and metrics from data- attributes.

    This change modifies the extension to make it able to work alongside the new attributes extension.

    • now gathers data from both data-ga-event-data and custom data- attributes
    • Made woost.extensions.googleanalytics.customdefinition.CustomDefinition.initialization optional
    • Added the client side method
    • Added the client side property
    • Generate data-ga- attributes for the element
  • Added an option to select a default image for Open Graph.

  • The pdf extension served files using the application/x-pdf extension. Corrected to application/pdf. Some user agents (notably, some versions of the Android download manager) couldn't deal with the first form. 

  • Fixed the default value for woost.models.TextBlock.image_close_up_factory.



The main changes in this version are the adoption of SASS, the support for alternative views on all blocks and the introduction of visual grids.

Requires cocktail/komovica.

  • Improvements to the woost.models.Block model.

    • Support different views per block type. The change allows all block types to support different views (like some blocks already did on their own, such as woost.models.PublishableListing or woost.models.NewsListing).
    • woost.models.Block.element_type is now a standard member of all blocks (most blocks ended up adding it anyway). The woost.models.ElementType member type is gone.
    • woost.models.Block.heading_type remains, but some of its values now reside in a new woost.models.Block.heading_display member
    • Blocks with a visible heading now default to a section/h1 combination
    • Most block members can now be set to a -- Default -- value, intended to respect the values set by the chosen view class
    • Rearranged the fieldsets / tabs for woost.models.Block, woost.models.TextBlock and others. The behavior member group has been renamed to publication.
    • woost.controllers.backoffice.AddBlockNode is replaced by woost.controllers.backoffice.BlockEditNode
  • Better integration with SASS.

    • Added libsass as a dependency
    • Support SASS code in the block embedded styles
    • Support SASS code in user styles
    • Renamed woost.models.Block.inline_css_styles to woost.models.Block.embedded_styles (requires a migration)
    • Added the woost.models.Block.embedded_styles_initialization member
    • Added the woost.models.Style.declarations_initialization member
    • Use cocktail.schema.CodeBlock for all style fields, with language set to SASS
  • Added slots to define footer blocks (most sites ended up defining these themselves).

    • Added the  woost.models.Configuration.footer_blocks member
    • Added the woost.models.Website.footer_blocks member
    • Added the woost.views.StandardView.site_footer_blocks element
    • Removed the woost.views.StandardView.vcard element
  • New API to create woost.models.File objects from filesystem paths and file-like objects.

    • Added the woost.models.File.import_file() method
    • Added a file parameter to the woost.models.File constructor
    • Deprecated woost.models.File.from_path()

    The new API can be invoked from the File constructor, which is convenient when mixed with the class method. Also, it supports loading files from file-like objects, not just file system files, and provides better control over which parts of the File instance should be initialized using data from the imported file.

  • Added support for visual themes and grids.

    • Added the woost.models.Theme model
    • Added the woost.models.Configuration.theme member
    • Added the woost.models.Website.theme member
    • Added the woost.models.Template.theme member
    • Added the woost.models.Document.theme member
    • Added the woost.application.Application.theme property
    • Added the woost.models.Grid model
    • Added the woost.models.GridSize model
    • Added visual rulers for the site's grid (activated by appending a #rulers hash to page URLs)
  • Added responsive navigation elements to the base site template.

    • Added the woost.views.SmallScreenNavigation view
    • Added the woost.views.StandardView.small_screen_navigation element
  • Added several events to customize blocks in a cleaner, standard way, avoiding the need to monkey patch block classes in common customization scenarios.

    • Added the woost.models.Block.initializing_view event
    • Added the woost.models.PublishableListing.selecting_items event
    • Added the woost.models.NewsListing.selecting_items event
    • Added the woost.models.EventListing.selecting_items event
  • Added a member to define alternative titles for menus.

    • Added the woost.models.Publishable.menu_title member
    • woost.views.Menu will now give preference to menu_title and fall back to the generic translation
  • Allow ContainerBlock to have background images.

    Added the following elements:

    • woost.models.ContainerBlock.background_image
    • woost.models.ContainerBlock.background_image_factory
    • woost.views.ContainerBlockView.background_image
    • woost.views.ContainerBlockView.background_image_factory
  • Added the woost.views.VCard view.

  • woost.views.IdentityBox now exposes a data-woost-auth-state attribute.

  • Provide a T variable in the site shell that exposes the cocktail.schema.TranslatedValues class in a convenient manner.

  • Attributes extension: refactored the element initialization code.

    • Added support for passing arbitrary context to initialization code blocks (the env parameter of woost.extensions.attributes.utils.init_element()  and woost.extensions.attributes.utils.iter_attributes())
    • Added attributes to cocktail.html.Element (following the same pattern of the Google Analytics extension) to control element initialization
  • The autohiding behavior of text_container in woost.views.TextBlockView should account for the heading_alignment property.

  • googleanalytics: handle missing attributes when invoking; don't trigger events unless both eventCategory and eventAction are defined.

  • Optimized the resolution of permissions that operate on whole types.

  • Cache the woost.models.Configuration.instance property.

  • Overhauled client side caching.

    The previous implementation used content hashing to produce the value for the ETag header. This is a very fragile approach, as CML based documents tended to produce inconsistent values (the declaration order for client parameters is not guaranteed, and cocktail.html.element.Element.require_id() includes a timestamp). Thus, the produced ETags varied between requests, breaking client side caching.

    The new approach uses timestamps as ETags, updating them whenever a document is rendered or one of its dependencies (as stated by cocktail.html.element.Element.depends_on()) is modified.

    Some observations:

    • The new system makes it unnecessary to produce the content for a request if the stated ETag matches the last known document state. The previous system needed to generate it in all cases, to compute the ETag hash and compare it with the one provided by the client.
    • Client side caching now requires a cache storage (the timestamp for each served document is stored in the cache)
    • Client side caching now requires explicit dependency definition (cocktail.html.element.Element.depends_on()), just like server side caching
    • The structure of the entries of the site's cache has changed (to add the timestamp), so be sure to flush the cache after applying this upgrade
    • A new property, woost.models.Publishable.cacheable_server_side, compliments the already existing woost.models.Publishable.cacheable. Server side caching is disabled for woost.models.File objects by default.


This release replaces the URL mapping system, introduces the staticpub extension and adapts to the translation API changes in cocktail 2.11.

  • Adapted to the translation API changes in cocktail 1.11.

    • Removed the woost.translations package, replaced with multiple .strings files
    • The directory skeleton for new sites no longer includes a translations package
    • The -menu suffix for the translation keys of model members becomes .backoffice.menu_label
  • Disabled several old extensions.

    • blocks
    • campaignmonitor
    • comments
    • facebookpublication
    • shop
    • twitterpublication
    • usermodels
    • webconsole
  • New URL mapping system.

    The previous system for parsing and building content URLs was severely limited:

    • Protocol and domains were set based on hard coded policies
    • Websites could only be mapped to domains
    • Languages could only be mapped to the first path component
    • The publishable object could only be mapped to the path
    • All those systems were essentially hard coded and not interoperable

    The new system provides a single, extensible point of configuration to push or pop information from/into content URLs.

    • Removed the woost.urlresolver module, replaced with woost.urlmapping
    • Renamed woost.application.Application.url_resolver to woost.application.Application.url_mapping
    • Changes to woost.models.Item.get_uri() and woost.models.Item.get_image_uri():
      • Return cocktail.urls.URL objects instead of plain strings
      • No longer accept "." as a value for their host parameter
      • Gained a website parameter
      • Can now receive arbitrary keyword parameters, to be forwarded to the URL mapping process
      • Removed the encode parameter
    • Removed the woost.models.Item._fix_uri() method
    • Changes to woost.controllers.CMSController:
      • Removed the woost.controllers.CMSController._process_path() method
      • Renamed woost.controllers.CMSController.canonical_redirection() to woost.controllers.CMSController._enforce_canonical_url()
      • Removed obsolete and deprecated members:
        • woost.controllers.CMSController.uri()
        • woost.controllers.CMSController.translate_uri()
        • woost.controllers.CMSController.image_uri()
        • woost.controllers.CMSController.language
        • woost.controllers.CMSController.authentication
        • woost.controllers.CMSController.LanguageModule
        • woost.controllers.CMSController.AuthenticationModule
    • Changes to woost.languagescheme.LanguageScheme:
      • Removed woost.languagescheme.LanguageScheme.translate_uri(), use woost.urlmapping.URLMapping.transform_url_request() instead
      • Removed woost.languagescheme.LanguageScheme.language_to_uri_component()
      • Removed woost.languagescheme.LanguageScheme.uri_component_to_language()
    • Changes to woost.models.Configuration:
      • Removed the deprecated woost.models.Configuration.resolve_path() method
      • Removed the deprecated woost.models.Configuration.get_path() method
    • Removed obsolete modules:
      • woost.controllers.language
      • woost.controllers.authentication
  • Introduced the staticpub extension.

  • Internal refactoring of the user actions system.

    The add_integral action was broken: it used a link to pass the desired type for the new object on its query string. Since it didn't use a POST, unsaved form data was not entered into the edit stack and was therefore lost.

    To fix this, user actions can now receive parameters (such as said type, or the relation they work uppon). This has caused many changes:

    •  The POST format for user actions changes; it can now include extra parameters and reference other form fields in the part that designates the selected targets
    • All the logic to select and activate a user action based on the current request has been moved to BaseBackOfficeController. Removed specific logic in ContentController, EditController, EditBlocksController, ChangeLogController and ItemFieldsController.
    • Changes to the woost.views.ActionBar class:
      • Removed the woost.views.ActionBar.action_parameter property
      • Removed the woost.views.ActionBar.submit_action_target property
      • Added the woost.views.ActionBar.selection_field property
      • Added the woost.views.ActionBar.relation property
      • Added the woost.views.ActionBar.hide_disabled_actions property
    • Changes to the woost.controllers.backoffice.UserAction class:
      • Changed the signature of woost.controllers.backoffice.UserAction.get_errors()
      • Changed the signature of woost.controllers.backoffice.UserAction.invoke()
      • Added the woost.controllers.backoffice.UserAction.get_parameters_schema() method
      • Added the woost.controllers.backoffice.UserAction.get_parameter_members() method
      • woost.controllers.backoffice.UserAction.get_dropdown_panel() now receives a reference to a woost.views.ActionBar object instead of the action's target
    • New actions and abstract base classes:
      • woost.controllers.backoffice.useractions.CreateAction
      • woost.controllers.backoffice.useractions.SelectRelatedObjectAction
      • woost.controllers.backoffice.useractions.RelateNewIntegralObjectAction
      • woost.controllers.backoffice.useractions.AddNewAction (replaces woost.controllers.backoffice.useractions.AddIntegralAction)
      • woost.controllers.backoffice.useractions.PickAction
      • woost.controllers.backoffice.useractions.PickNewAction
      • woost.controllers.backoffice.useractions.UnlinkAction
    • Reimplemented woost.views.ItemSelector as a CML template, use a woost.views.ActionBar instead of a custom set of buttons
    • The dropdown menu for the new and add_new (the old add_integral) actions is now defined by the get_dropdown_panel() of their CreateAction base class. Until now it was replicated in several places.
  • Support SVG files in woost.views.Image.

  • Introduced default document templates.

    Until now, each document had to specify its template explicitly. This presented two problems:

    • It was wasteful. In most cases, all documents of a type used the same template. Having each instance specify their template was inefficient (template objects ended up with a list containing all related documents using the template, which could escalate quickly).
    • It made it difficult to choose templates based on dynamic or contextual parameters. For example, using different templates depending on the active website.

    The new system still offers the woost.models.Document.template member, which works as before, but couples it with new elements that make it possible to specify site wide default templates for all instances of a document type:

    • Added the woost.models.Document.get_template() method
    • Added the woost.models.Document.get_default_template() method
    • Added settings in woost.models.Configuration and woost.models.Website to specify the default templates for all standard woost.models.Document subclasses (default_page_template, default_news_template and default_event_template)

    As a side effect, a new member subgroup has been added to both woost.models.Configuration and
    woost.models.Website (presentation.appearence), and the theme member for both has been relocated inside it.

    Implementers should replace snippets like this:

    default_template = schema.DynamicDefault(
        lambda: Template.get_instance(qname = "...")

    with an override of the woost.models.Document.get_default_template() method.

    A migration is provided to automatically remove redundant references to a default template. It does a best effort attempt; site developers should check the results and adjust as needed.

  • Make it possible to add CSS classes to documents.

    • Added the woost.models.Document.styles member
    • Added the woost.models.Style.applicable_to_documents member
  • Enable blocks to customize the HTML for their heading.

    • Added the woost.models.Block.custom_heading member
    • Added the custom option for the woost.models.Block.heading_display member
    • Added the woost.models.Block.get_heading() method
  • Changes to woost.models.Document.inner_title

    • Now supports HTML
    • Changed its visible name, to align it with woost.models.Block.custom_heading
    • woost.views.BaseView.get_main_title() now ignores it
    • Add a with_custom_heading CSS class to woost.views.StandardView if the active document defines woost.models.Document.inner_title
  • Added the woost.grid client side package

  • forms extension: Added the woost.extensions.forms.fields.OptionFieldOption.enabled member.

    This makes it possible to remove options from a closed set field without affecting the requests that may have selected it and been already stored.

  • Optimized woost.models.Item.get_cache_expiration_for_type() for indexed members

  • variables extension: support passing positional parameters to dynamic variables

  • Added the woost.models.utils.import_remote() function.

    Also, added the and properties as a convenience for calling the new function.

  • Support javascript: URLs in woost.models.URI objects.



The main features of this branch are the automatic generation of robots.txt files, an overhauled extension for sitemaps and more flexible APIs for querying publication state.

Requires cocktail/mezcal.

  • Make publication state checks more flexible.

    Until now, publication checks (the woost.models.Publishable.is_published() / woost.models.Publishable.is_accessible() methods, and the woost.models.IsPublishedExpression / woost.models.IsAccessibleExpression classes) only considered the active language and website when computing their results. This changeset makes it possible to indicate which languages and websites should be considered. The default behavior will still use the active context, so the changes should be backwards compatible (except for the "any" value in the methods; see below).

    • Make the language and website parameters to woost.models.Publishable.is_published() and woost.models.Publishable.is_accessible() accept multiple values, as well as the new woost.models.Publishable.any_language / woost.models.Publishable.any_website constants.
    • Added the language and website properties and constructor parameters to woost.models.IsPublishedExpression and woost.models.IsAccessibleExpression
    • The website parameter of woost.models.Publishable.is_published() / woost.models.Publishable.is_accessible() no longer accepts an "any" value; pass woost.models.Publishable.any_website instead.
  • Automatically generate a robots.txt file, relocate robots_should_index.

    Until now, disabling indexing for specific content was only possible for instances of the woost.models.Document model since the CMS used a <meta> HTML tag to achieve this, therefore requiring an HTML template). With this change, the CMS will now automatically generate a robots.txt file, based on the robots_should_index member. As a consequence, the member has been moved to the woost.models.Publishable model.

    Sites can customize the generated robots.txt file using any of the events provided by woost.controllers.robotscontroller.RobotsController, or outright disable the automatic generation by
    placing a custom robots.txt file in the document root of the web server.

  • Complete overhaul of the sitemap extension.

    • Introduced a woost.extensions.sitemap.SiteMap model, which makes it possible to define (and customize) multiple different site maps.
    • It is now possible to generate multiple URLs for each element (for example, for pages with query string parameters or dynamic paths)
    • Support for multi language site maps, using rel="alternate"
    • Automatic declaration in the robots.txt file
    • <priority> is now omitted by default, unless explicitly set to anything other than 0.5
    • <lastmod> is no longer included in the default site map; computing this reliably is impossible for most content
    • The woost.models.Publishable.sitemap_indexable member has been removed; use woost.models.Publishable.robots_should_index from the core instead
    • Moved the site map configuration members in woost.models.Publishable to the meta.robots tab
  • Added the woost.models.Website.get_published_languages() method.

  • Support multiple background images in text blocks.

  • Use the woost.views.BaseView.get_main_title() method to obtain the document's main heading.

  • Make the woost.views.Link view add the hostname to its target URL when necessary.

  • Limit the size of SVG thumbnails in the backoffice.

  • Optimized woost.models.Item.get_cache_expiration_for_type() for indexed members.

  • Added the woost.publishable and woost.navigationPoint client side variables.

  • Cache the navigation for small screens by default.

    The menu for small screens can be expensive to render on sites with a big page tree. This changeset enables caching for it, making all pages share the same rendering, which can lead to a substantial performance improvement. Note that as part of the change, the menu now selects the active menu entry client side.

    Note that the site will need to configure a storage for cocktail.html.rendering_cache to benefit from this.

  • woost.models.CachingPolicy always included query strings in the caching key.

    This was redundant (the key was qualified by default with the full set of parameters) and also made it impossible to ignore certain parameters using woost.models.CachingPolicy.cache_key_expression).

  • Allow container blocks to have a link

    • Added the woost.models.ContainerBlock.link_destination member
    • Added the woost.models.ContainerBlock.link_parameters member
    • Added the woost.models.ContainerBlock.link_opens_in_new_window member
  • Improvements to the 'Add block' dialog in the backoffice.

    • Better layout
    • Search box
  • Improvements to

    • Added a fetch() function. fetch(Model, *args, **kwargs) is the same as list(*args, **warkgs)).
    • Added tr as an alias for cocktail.translations.translations
    • Automatically import several classes of the Python standard library that are used frequantly in interactive sessions:
      • decimal.Decimal
      • collections.Counter
      • collections.defaultdict
      • datetime.time
      • datetime.datetime
      • datetime.timedelta
  • Complete overhaul of cost calculations on the ecommerce extension.

  • Added an scheme parameter to woost.urlmapping.URLMapping.get_url() and woost.models.Item.get_uri()

  • Added the BECOME_DIV option for woost.views.Link.inactive_behavior

  • locations extension: Added the woost.extensions.locations.location.Location.get_country() method

  • Make woost.models.objectio more convenient.

    • woost.models.objectio.ObjectImporter now has an objects property, making it easier to access all the objects it imported
    • The constructor for woost.models.objectio.ObjectImporter now accepts a file or a JSON string (no need to instantiate and load in two steps)
    • Most woost.models.objectio.ObjectImporter attributes can now be set through the constructor
    • Import the most relevant woost.models.objectio classes automatically into sessions
  • Improve the results of some image processing effects on palette based images.

    Added the woost.models.rendering.imageeffects.requires_rgb() decorator to temporarily convert images to RGB, applied
    it to several image factory effects.

  • googlesearch extension: Site Search discontinued, moved to the Google CSE Json API.

  • Added the woost.models.with_default_template class decorator, to simplify the declaration of site wide default templates for site specific models.

  • Introduced changes to minimize the risk of keeping object cycles alive when rendering pages, which ramps up memory consumption over time.

    • Call cocktail.html.Element.dispose after rendering document templates
    • Delete the references to block and view in woost.models.Block.initialization after executing the code snippet
  • Introduced the woost.models.PublishableObject mixin class.

    The new mixin allows models to gain all the behavior of the woost.models.Publishable class, without being forced to extend it, which can be undesirable in many cases.

    Also, the following supporting functions have been added:

    • woost.models.get_publishable()
    • woost.models.get_publishable_by_full_path()
  • Improvements to woost.urlmapping.DescriptiveIdInPath:

    • Added the woost.urlmapping.DescriptiveIdInPath.applies_to_publishable() method
    • Added the woost.urlmapping.DescriptiveIdInPath.allow_slashes_in_title property
    • Added the woost.urlmapping.DescriptiveIdInPath.escape_title() method


  • Generalized the support for application wide contextual properties.

    • Introduced the woost.application.ContextualProperty class
    • All existing contextual properties are now implemented as subclasses of woost.application.ContextualProperty
    • Added the woost.application.Application.clear_context()  method