August 6th, 2010

Apostrophe Updates

Tom Boutell
Chief Software Architect
Apostrophe has received quite a few fixes and improvements over the past few months. We've made upgraded releases of our open source software available. To learn more, visit the Apostrophe developer site.

Read on for a changelog of what's new in four Symfony plugins that go into practically every Apostrophe site: apostrophePlugin and apostropheBlogPlugin (which we created) and sfJqueryReloadedPlugin and sfDoctrineActAsTaggablePlugin (which we contribute to).

These updates concentrate on bug fixes and stability but there are also some new features that did not require backwards incompatible changes. These release contain several months' worth of fixes, so if you are using plugin:install to install Apostrophe we strongly recommend that you upgrade.

A fair amount of refactoring has also been done to make it much easier to extend our work at the project level.

If you are using svn:externals to stay up to date with our 1.4 stable branch then these changes are old news to you, however the release notes contain a neat list of what has changed which may still be of interest.

We have also released updates to sfDoctrineActAsTaggablePlugin and sfJqueryReloadedPlugin to ensure that you have all of the pieces you need after upgrading. Notably, sfDoctrineActAsTaggablePlugin now offers a user-friendly tag widget renderer; use it to progressively enhance your Symfony form's tags widget.

The changelogs for all four plugins follow.


apostrophePlugin 1.4.1

  • Admin: aUserAdmin and aGroupAdmin now use a filter subclass that removes most fields, preventing explosive memory use when interesting relations are added. You can override to change this
  • Browser: cross-browser cleanup
  • CSS: CSS cleanup
  • CSS: Fixed bug where the media library was ignoring use_bundled_stylesheet
  • CSS: fixed slideshow CSS scoping
  • CSS: stylesheets should be loaded before javascript files, reversed order of the include calls
  • Configuration: app_a_default_published added as a more intuitive alternative to app_a_default_on
  • Development: aArray::isFlat checks whether an array is a flat array: numerically indexed by consecutive integers starting from zero, no ifs ands or buts
  • Development: aDate::mysql() method takes a PHP timestamp, MySQL datetime or MySQL date (defaulting to now) and returns a MySQL datetime format string suitable for calling setCreatedAt() or similar. Takes advantage of aDate::normalize() & centralizes that pesky date() format string for MySQL in one place
  • Development: aText::limitWords(): changed ellipsis from three periods to the unicode character
  • Development: getRealPage fixed: no longer returns the "global" page if there is no real page
  • Development: updated aHtml::limitWords to accept the append_ellipsis option that aString::limitWord already accepts
  • Email: single or double quotes in the label of an obfuscated mailto link no longer show up with slashes in front of them in the page
  • Engines: Fixed an issue with the page property of engine action classes
  • Engines: aDoctrineRoute now also supports passing engine-slug as a parameter.
  • Engines: engine-slug parameter now pops the target engine page properly. Thanks to Avi Block
  • FCK: FCK layout improvements
  • FCK: turned off the StartupFocus parameter in the FCK config we bundle with Apostrophe, which either didn't work at all or created problems depending on context
  • Feed Slot: fixed a bug with the title being a link in the feedItem template
  • Feed Slot: now accepts an itemTemplate similar to the slideshowItemTemplate
  • Feed Slot: titles as links now work as expected in the feed slot
  • Feed Slot: updated the aFeed slot to accept options for passing attributes and styles through the feed in addition to just markup
  • Feed slot: posts limit option correctly passed as a number
  • I18N: removed all of the text transform styles from the plugin. Those we like are now in the sandbox where you can easily remove them for better I18N
  • JavaScript: Fixed cross-browser issue with aMultipleSelect
  • JavaScript: New jquery ui theme
  • JavaScript: Update jQuery UI to match last stable 1.3.x jQuery release. Moving to 1.4.x will require addressing some incompatibilities
  • JavaScript: jQuery cleanup
  • JavaScript: you can now hit Return to save a new item in aMultiSelect
  • Markup: Fixed accessibility and standard compliance bugs (a few compliance issues remain)
  • Markup: editPdfSuccess markup corrected
  • Markup: editVideoSuccess and _editImage partial markup corrected
  • Media: Added aMediaItem::getImgSrcUrl method
  • Media: Deprecated use of actual_slug to bring users back from media repository in favor of actual_url; fixed our own examples
  • Media: added width and height attributes to the image tag output by getEmbedCode in PluginaMediaItem.class.php. This speeds up rendering for all browsers across the board
  • Media: all media slots (when in areas, not as singleton slots) now display a placeholder div where appropriate
  • Media: alphabetized media categories in the multiple select drop down
  • Media: fixed error with slideshows in global and virtual pages, associated with fixed bug in aTools::getRealPage()
  • Media: fixed undefined index error in slideshow slot when no width parameter is specified
  • Media: gd backend now recognizes more cases where an image need not be modified, which preseves transparency and improves performance
  • Media: ghostscript automatically killed after 5 seconds if it is not able to determine PDF dimensions in that time. Works around ghostscript bugs with occasional slightly dodgy PDFs
  • Navigation: Tab and accordion navigation now outputs ancestor classes consistently
  • Navigation: better support for the "unpublish an ancestor to create pages that are not visible in navigation elsewhere in the site" technique
  • Navigation: fixed bug in accordion navigation that caused improper ordering classes to be placed on nav-items when archived pages also existed in navigation element
  • Navigation: getAccordionInfo no longer returns archived ancestors when $livingOnly is true
  • Navigation: getAccordionInfo works in all situations
  • Navigation: getAncestorsInfo now has an optional $livingOnly flag to return only ancestors that are not archived
  • Performance: new app_a_search_hard_limit option prevents out of memory errors when searching very large sites. If you have 1,000's of pages see the documentation for more information about how to set this
  • Refactoring: $aPageTable->checkUserPrivilegesBody() is the core privilege checker method; extend this, calling the base version and adding your own checks, and you won't have to worry about caching or rewriting privilege names, both of which are taken care of by the checkUserPrivileges method first
  • Refactoring: Fixed missing parent::configure() calls in the media subtype forms. Now you can modify the behavior of all media subtype forms by editing the configure() method of the aMediaItemForm class at project level
  • Refactoring: aPageTable::checkPrivileges is now a wrapper around $aPageTable->checkUserPrivileges(), which is easier to extend without static method inheritance problems
  • Refactoring: all form classes and many other classes, such as aTools, now extend a Basea* class so you can override them and extend the base to avoid duplicating code
  • Refactoring: the privileges portion of the page settings form is broken out to a single allPrivileges partial so that you can easily override that to add or remove parts of it when templating out the page settings form
  • Samples: removed twoColumnTemplate from app.yml sample
  • Search: Zend Lucene can throw exceptions if it doesn't like search syntax. Catch the exceptions and report no results
  • Search: category names now trigger search matches in the media repository
  • Search: don't let workloads requested by consecutive failed invocations of rebuild-search-index build up a backlog of redundant indexing to be done
  • Security: breadcrumb partial no longer outputs archived pages when logged out
  • Security: checkUserPrivileges is now responsible for converting 'edit' to 'edit|manage' in one consistent place
  • Security: cleaned up logic determining when "this page" button and its contents are rendered. Editors and managers can use "this page" properly
  • Security: consistent presentation of permissions option in media type forms
  • Security: custom secureSuccess message in sandbox project when you are logged in with insufficient permissions, behaves like a 404 by default
  • Security: don't show the heading for the page permissions area if both privilege widgets are disabled for this user
  • Security: explicit permissions are not checked for virtual pages (this introduced DQL bugs granting everyone edit permissions to them, you should be using the 'edit' flag to a_area or a_slot to programmatically determine who has rights to a virtual page)
  • Security: improved privilege cache
  • Signin: removed remember me button from the signin form partial since its default behavior in sfDoctrineGuardPlugin is not what users expect (i.e. it doesn't work)
  • Slots: Added an aUI call after slot is saved to reactivate buttons etc.
  • Slots: app_a_new_slots_top option now works properly. Thanks to martin79
  • Slots: editing-now class now removed from slots properly after save
  • Slots: slots can now be nested more deeply, often needed in the blog plugin
  • Slugs: Add checks and fixes when renaming a page creates a slug conflict
  • Slugs: Fixed bug that caused engines to not work properly with utf-8 slugs
  • Slugs: leading slash required when editing slugs
  • Slugs: new require_leading_slash option to aValidatorSlug
  • Testing: minor tweaks to the functional testing methods
  • Variants: The new app_a_allowed_slot_variants setting determines which slot variants are permitted by default. You can always override it with an explicit allowed_variants option in an a_slot or a_area call

apostropheBlogPlugin 1.4.1

  • Fixed new category validator, now uses post validator to clean values.
  • Fixed improper filtering of categories on show success of blog and events.
  • Single post blog slot now searches for titles correctly via slots, rather than looking at the obsolete title field. The event slot does too.
  • Fixed a logic problem regarding the slideshowOptions arrow in the slot component classes
  • aEventSingleSlot uses the correct form, allowing the slot to be saved
  • Fix for new categories validator
  • Fix for new categories validator when user can't add new categories
  • You can have just events and no blog, or vice versa, or both
  • Fixed form class methods to properly match method signature of doctrine parent classes
  • Removed edit categories link when editing events and posts
  • Fixed inconsistencies in blog and event sidebar tag counts. Future dated posts and events no longer contribute to tag count. Also posts with multiple categories were formerly counted once for each category
  • Fixed routing problem with date pager for events
  • Fixed misnamed value for categoryColumn
  • Edited metadata to only show end dates when it is different from the start date address
  • Fixed a bug where it was possible for aBlogItem to be undefined when the slot is used as a singleton and still had no content
  • Cleaned up event meta partial. Now only shows times when it is a single day event with different start/end times. Multi day events do not show times, as this leads to confusion. Times for multi-day events are better explained in the event body
  • Routing no longer needs to specify what filters are applied for each route
  • Two column slot template brought up to date
  • Added robot blocking back for multiple filtering to prevent your server from being DOSed by Google Search Appliance (this does not harm SEO because everything is accessible via a single filter at most)
  • When viewing events in an engine index events are shown whenever their date range overlaps the filtered date range
  • Fixed bug where filtering could break admin view when a selected filter value was deleted
  • Using unset to clear filters instead of setting them to null
  • Allow no value to be set when deselecting filters
  • Changed default ordering of categories to be by name
  • Made it easier to override default templates
  • Sidebar area was not using the sidebar toolbar for richtext editor in the twoColumnTemplate
  • Author field should be unset when not logged in as an admin
  • Unfloated the selected tag to correct display
  • Being a user for a category means that you can categorize your posts into it. It does not mean that you can edit other people's posts that happen to be in it. Only blog admins have blanket permission to do the latter. You must be a member of the editors group (if there is one) to be listed as a category author. This limits the size of the dropdown and is necessary for the same reasons as in the page settings dialog. Added an overridable getUseFields method to aBlogCategoryForm::setup() making it possible to add fields without getting clobbered by the useFields() call in setup()
  • There was a significant bug designed into the blog sidebar relating to tags and the way the blog admin handled form submissions for the page. There is now a new reuseable tagWidget in the DoctrineActAsTaggable plugin. This widget closely resembles the way the flickr interface for managing tags works. It is much more stable and fixes the bug we had with accidentally submitting the sidebar
  • Brought new tag widget over to Events
  • Titles live in Apostrophe text slots, which contain preescaped HTML (boring HTML with only entities). When slugifying a blog post we need to unescape the HTML first as the slugifier expects (and is happy to deal with) a real UTF8 string
  • Cleanup of tags, fixed categories bug where the permissions check was not wrapped around the edit button
  • Fixed blog sidebar category layout bug in IE7
  • Permalink displayed in post and event editor now displays the date in the url
  • Fixed copy/paste error, a_blog_post changed to a_event
  • Made it easier to override engine settings forms
  • The blog plugin had markup in javascript inline in a partial. This causes validation errors unless you wrap the script in CDATA - Fixed this in 1.4 and trunk
  • updated blog plugin to use jquery ui 1.7.3 by default if it is not set in settings.yml
  • published_at now has a default value.
  • Altered formating of dates in event admin.
  • Event admin was using a blog route for removing filters.


  • Filter tags array for empty tags
  • fixing schema in order to get valid yml syntax - see
  • Fixed ActAs documentation for schema.yml; documented "link_function" option to tag_cloud()
  • Created a renderer for tag widgets that provides user friendly tag editing features
  • Added tag-input classname to the input for the new tag widget so that it is compatible with pkTagahead if necessary
  • Found a bug in some logic in the component.class
  • Fixed a bug with the new tag widget
  • Documented the new tag widget renderer

sfJqueryReloadedPlugin 1.4.3

  • Updated jQuery UI. (We still haven't moved to jQuery 1.4.x by default due to persistent incompatibilities with important jQuery packages needed by Apostrophe. We're working on it.)
Tom Boutell
Chief Software Architect