- If a JPEG file has EXIF data such as the description, credit, etc. this information is
now copied into new properties of the attachment field and made available automatically
on corresponding new schema properties of
apostrophe-imagespieces. req.data.globalnow becomes available even before its joins and area loaders are executed, asreq.aposGlobalCore. This allows modules such asapostrophe-pieces-orderings-bundleto avoid recursive scenarios and performance problems.- Sortable columns in the manage view can now indicate whether the first click sorts forwards
or backwards, simply by specifying the sort direction in the usual MongoDB way with
1or-1. - Sortable columns can now be toggled from "no sort" to "forward" to "backward" and back to "no sort" again, and the hover state indicates all of these "next" states.
- The
limitByAllandlimitByTagoptions of theapostrophe-pieces-widgetsmodule now correctly remove these fields from theshowFieldsof the select element that chooses how the widget will select content to display. - To select many consecutive pieces or pages quickly in the "Manage Pieces" and "Reorganize Pages" views, hold down the shift button while clicking a second piece. All pieces between the two pieces selected so far will be chosen.
- Fixed a bug where removing an array item other than the last could cause a failure of the array field editor if the last array item were active. Thanks to anwarhussain93.
- Documentation issue only. No code changes.
Unit tests passing.
Regression tests passing.
-
npm auditissue:nunjucks- Created maintenance-only fork of
nunjucks2.x as@apostrophecms/nunjucks - We will use Nunjucks 3.x in Apostrophe 3.x, this is a maintenance fork only
- Addressed dependency on old version of
chokidarinnunjucks2.x
- Created maintenance-only fork of
-
npm auditissue:clean-css- Verified this module offers no significant improvement in minification over the
compressflag ofless - Removed this module from ApostropheCMS
- Verified CSS still minifies
- Verified this module offers no significant improvement in minification over the
-
You may now sort the "Manage Pieces" view by clicking on any column that has a
sortproperty. By defaulttitleandupdatedAtare now sortable. When usingaddColumnsspecify asortproperty like:
sort: {
title: 1
}For more information see custom columns and sortable columns for the "manage pieces" modal.
-
Fixed several situations formerly requiring a page refresh before editing. More such fixes to come. Thanks to
hexitexfor the bug reports and insight into the causes. -
A recent change broke the display of the minimum image size to the user. This has been fixed.
-
A new warning has been added for failure to use
arrangeFieldscomprehensively for all of your fields to make the "manage pieces" modal as clear as possible for the user. -
Fixes were made allowing contextual editing of more types of content nested in
objectfields on the page. Thanks to bharathkumarc.
Many thanks to Michelin for making much of this work possible via Apostrophe Enterprise Support.
Unit tests passing.
Regression tests passing.
- Bug fix: a crash in the lock refresh route was possible if an advisory lock was taken away by another tab or user. Thanks to
hexitexfor the report and the solution.
Unit tests passing.
Regression tests passing.
- When using the
apostrophe-pieces-importmodule, you may now set theimportAsRichText: trueoption on anareaorsingletonfield to import markup rather than treating it as plaintext. With this setting in place the behavior matchesapostrophe-pieces-export. Also note that bothapostrophe-pieces-importandapostrophe-pieces-exporthave been updated to be more compatible with one another.
Unit tests passing.
Regression tests passing.
- If the
APOS_ALWAYS_COPY_ASSETSenvironment variable is set, always copy assets rather than symlinking them. This is useful when running under Docker. Thanks to hexitex for this contribution. See also building Docker images for Apostrophe projects.
Unit tests passing.
Regression tests passing.
- Stability improvement: search index method of the
tagstype will not crash if thetagstype is somehow truthy without being an array.
Unit tests passing.
Regression tests passing.
- Default values are now respected by the global doc. Specifically, if your field has a
defproperty when the global doc is first created, it will be set accordingly. In addition, if a field is added to the schema and your site is restarted, it will also be added with the correct default at this time. Tests coverage has been added for this scenario.
Unit tests passing.
Regression tests passing.
- The conflict resolution mechanism for simultaneous edits has been improved. Previously, Apostrophe tracked how long it had been since the "last edit" by the previous person. But if the browser window closed without sending an "unlock" message, that "last edit" might be a very long time ago. This led to nuisance confirmation prompts and a tendency to ignore their message.
Beginning with this release, the browser instead actively refreshes the lock periodically. And if the browser does not do so for 5 minutes, the lock is automatically discarded.
This greatly reduces the chance that you will see a "someone else is editing that document" message when this is not actually the case.
However, do note that you will no longer see an indication of the "last edit" time. This is because this time was never really meaningful for the "Edit Piece" dialog box, and often misleading for on-page editing as well. Instead, you may assume that the other person is still at the very least on the page in question if you see this message at all.
- Although it was released separately as part of the
laundermodule, and annpm updateshould fetch it for you automatically, it should be mentioned thatlaunderversion 1.1.1 has been released and prevents crashes if thevalueof some of your select element choices is null or undefined. Such choices do not work and cannot be selected reliably (only strings and numbers are supported, including the empty string), but since versions prior to 1.1.0 did not crash on such choices, we have patched 1.1.1 to also tolerate their presence.
Thanks to our Apostrophe Enterprise Support clients for making these enhancements possible.
- The case-insensitive sort for filter choices no longer crashes if a choice cannot be converted to a string. Thanks to Fawzi Fakhro.
Unit tests passing.
Regression tests passing.
- A recently introduced change broke the filtering that prevented users from selecting too-small images when
minSizeis in effect. This has been corrected. Note that site visitors never actually saw too-small images because filtering did take effect later in the process. - Numbers (in addition to strings) are now permissible choices for select elements. If the choice selected is a number, a number will be stored in the field. Most of this fix is in the
laundermodule but there is a small fix in apostrophe core as well. - If a doc is in the trash already, the edit dialog box should have a "Rescue" button rather than a "Trash" button on the "More" dropdown menu.
booleanfields can now be mademandatory. If a boolean field is mandatory, the form will not validate unless the user selects "Yes." This is useful for simple "terms and conditions" forms. You must specify a message to be shown to the user if they do not select "Yes," like this:
{
name: 'toc',
label: 'Accept the Terms and Conditions',
type: 'boolean',
// Displayed if you try to save without picking Yes
mandatory: 'You must accept the Terms and Conditions to continue.',
// Always displayed
help: 'I have read and accept the Terms and Conditions.'
}
Although the documentation formerly claimed that required: true would have this effect for boolean fields, it was pointed out that this functionality did not work, and as a result far too many sites already use required: true for booleans in a way that would break if we implemented the original documented behavior. Therefore we are changing the documentation to match this new implementation that maintains backwards compatibility.
Unit tests passing.
Regression tests passing.
- Built-in migration progress meter is much improved. The new implementation:
- Does not display anything if the task completes within 1 second;
- Allows work to begin even before the total number of items is known;
- Has a much more stable ETA;
- Does not crop the total off the far end;
- Displays steps/sec (very useful metric for development); and
- Has highly stable formatting (not distracting to the eye).
- Eliminates unnecessary warnings about unconsumed promises in migrations.
Unit tests passing.
Regression tests passing.
- You can now set permissions for many pieces at once via the new "set permissions for..." batch operation in the "manage pieces" dialog box. Batch operations are accessible via a dropdown at the bottom of the dialog box after you check the boxes to select various pieces. Note that if you check the box to select all the pieces on this page, you will be asked if you want to select all pieces. So it is possible to set the permissions of all of the pieces at once.
Note that permissions have no effect on file attachment URLs unless you use the optional apostrophe-secure-attachments module. Once you add that module, the new batch operation becomes a powerful way to lock down all of your PDFs at once.
- The "Select Everything" checkbox for pieces, which becomes accessible after you "Select All" pieces on the current page, now operates much faster on large databases and does not block the main thread of browser execution for an extended time.
Thanks to our enterprise clients, including Michelin, for their support of our work on these items.
Unit tests passing.
Regression tests passing (including new migrations test).
- Most migrations were failing when run in a non-interactive session. This was due to a stray piece of code that tried to interact with the progress meter when it was not available. This has been fixed. This was the underlying major issue in version 2.77.0.
- The recent migration to set the
docIdsandtrashDocIdsproperties of attachments correctly, allowing them to become inaccessible at the proper time, now runs and completes correctly, at the end of which all attachment permissions are properly restored. This resolves the issue that began with version 2.77.0. - The migration was also updated to avoid any chance of needlessly disabling permissions on a temporary basis during the migration run.
- If you temporarily lost access to your media due to running migrations with 2.77.0, which was available for a few hours today, you can restore access with the following command line task:
node app apostrophe-attachments:recompute-all-doc-references
If you manually set your permissions globally as a workaround, you should run this task to reset them appropriately:
node app apostrophe-attachments:reset-uploadfs-permissions
Although there is no reason to expect a recurrence of this issue, these command line tasks will continue to be available going forward, just in case.
Our regression tests are being updated to prevent a recurrence by
noninteractively invoking apostrophe-migrations:migrate
and checking for a clean exit code.
Unit tests passing.
Regression tests passing.
- Unfortunately the new migration in 2.77.0 appears to have caused
all permissions to revert to 000 on uploaded media on at least one site.
In an abundance of caution we have pushed out 2.77.1 which does not
carry out that migration. We are working on 2.77.2 which will carry it out
properly. You may restore your permissions with
chmod 644 public/uploads/attachments/*, if you are using S3 you can do this by restoring public access to each file, for Azure the suffix added to the name to disable each file would need to be removed. Fortunately this issue was caught quickly so there are probably no instances of the latter two in the wild.
We apologize for this serious issue and will provide a complete postmortem with 2.77.2.
-
The home page now works correctly when it is a pieces-page powered by
apostrophe-pieces-pages. Specifically, the URLs of pieces are generated correctly in this situation. This allows the home page to be a blog page, for example. Regression tests have been added to ensure this does not break in the future. -
Attachments (files) now become inaccessible properly when the last file or image piece that directly contains them moves to the trash. Formerly, attachments were incorrectly marked as "part of" pages that merely loaded them as part of a join or similar relationship. A migration has been added to correctly reset the
docIdsandtrashDocIdsarrays of all attachments on a one-time basis after which they will be tracked properly going forward. -
Migrations now have a progress display when iterating over all documents. This progress display automatically goes away if the migrations task is not running with access to a TTY (for instance, it is running in a deployment pipeline). You may note that not all migrations use this feature; generally the most time-consuming will however.
-
You can now specify a projection for a reverse join without the need to explicitly include the
idsField, or even know what it is. This was one of several reasons why developers often gave up on projections for reverse joins, or went back to the old approach of specifyingidsFieldrather than usingreverseOf.
Here is an example from the apostrophe-samples project:
// Forward join: in schema of products
{
name: '_specialists',
type: 'joinByArray',
withType: 'specialist',
label: 'Specialists',
help: 'The right people to ask about this product.'
}// Reverse join: in schema of specialists
{
name: '_products',
type: 'joinByArrayReverse',
withType: 'product',
reverseOf: '_specialists',
projection: {
_url: 1,
title: 1
}
}Note that we can also project
_url: 1to get all the fields necessary to populate_urlwhen the product is fetched, even though it is not a real property in the database.
-
Unnecessary schema validation errors are no longer thrown when using
joinByOneReversewithreverseOf. -
Schema fields named
formatare now allowed for pieces. There was a conflict with the UI code and backend routes of the "Manage Pieces" dialog box. -
"Drag and drop" now works properly for widgets that have just been added to the page. There is no need to refresh the page first.
Unit tests passing.
Regression tests passing.
- Removed unneeded call to
self.apos.utils.readOnlySessioninapos.notify, preventing crashes when this is invoked from a command line task. This fixesapostrophe-favicons. - Also updated
self.apos.utils.readOnlySessionso it will gracefully ignore calls made with no session inreq(typically command line tasks). - Eliminated uses of
async/awaitin core unit tests. This module still supports Node 6.x, so we use promises directly, not via async/await, in core code; of course you can stillawaitmost of our APIs in your own projects, becauseawaitworks with anything that returns a promise. - Fixed a bug that prevented page permissions from propagating properly when "Apply to Subpages" is checked in "Page Settings." Thanks to Mayank Bansal. Unit tests were also added to prevent a regression in the future.
- A bug that prevented the home page type from being changed via the UI in certain situations has been fixed.
Unit tests passing.
Regression tests passing.
- Email schema field type added. Thanks to Andrea Di Mario.
- Developer warnings for bad
showFieldsconfiguration now apply to all field types that supportshowFields. - Schemas are now validated for nested
arrayandobjectschemas, giving developers more information to help them fix their code. - The
poll-notificationsAPI now runs as middleware that is scheduled as early asreq.userbecomes available, avoiding the overhead of loadingreq.data.globalin this frequently polled API. - The
poll-notificationsAPI does not crash if theaposobject has been destroyed. This is not an issue for typical sites. However, this fix removes scary error messages displayed by the very useful apostrophe-monitor module, which is similar tonodemonbut specialized to Apostrophe for much faster restarts. - Although technically released in the
moog-requiremodule, not here, a recent fix in that module bears mentioning because it prevents bothapostrophe-monitorandapostrophe-multisitefrom misbehaving when the options objects of modules are modified. Specifically, the modifications are now reliably distinct for eachaposobject. - The logic that removes certain typically unwanted buttons from CKEditor is now conditional and does not remove them when they are explicitly requested in the toolbar. Thanks to Fredrik Ekelund.
- Placeholder markup when a pieces widget is empty. Although not often used directly, this template is often copied as a starting point.
- An open "add widget" area menu now appears above any hovered widget controls rather than being lost behind them.
showFieldssupport for fields of typecheckboxeshas been restored.- The "recursion warning" that appears when the same doc is loaded more than 5 times in a single request can now be suppressed on a per-request basis by setting
req.suppressAreaLoaderRecursionWarningstotrue. However the runaway loading process is still prevented. This is mainly of use for workflow API routes that examine many documents but are OK with stopping in this situation without generating extra log messages.
Thanks to Michelin for sponsoring much of this work through Apostrophe Enterprise Support.
Unit tests passing.
Regression tests passing.
- If a user has the type-specific
admin-productpermission, they should always be able to view aproduct, no matter whether it is published or not. This logic was correct for editing but not for viewing. Fixed a bug that led to crashes with the workflow module in this scenario.
Thanks to Michelin for making this fix possible via Apostrophe Enterprise Support.
Unit tests passing.
Regression tests passing.
- An "Undo" button has been added for the "Remove Widget" feature. Although such changes can be undone via "Page Versions," that feature is advanced and somewhat hard to find, whereas this simple "Undo" button is immediately helpful to most users.
- Apostrophe now displays warnings for several common developer errors. Previously it was difficult to understand why a module didn't work if
extendwas missing for certain common cases, like a-widgetsor-pieces-pagessubclass module. We will expand these warnings over time; options are provided to disable them if they do not apply to your situation. - The server side notification persistence feature introduced in version 2.74.0 led to an intermittent bug: the "long polling" used to deliver notifications quickly interacted badly with the "resave" behavior of Express sessions, resulting in frequent loss of other session changes, such as draft/live mode switching. This has been fixed. Since we cannot disable
resavewith the standard session store in Apostrophe 2.x, anapos.utils.readOnlySession(req)method was added, and the route that "long polls" for new notifications now uses it to disable any modification to the session for the duration of the request. limitByAll,limitByTagandlimitByIdoptions forapostrophe-pieces-widgets. When set the user is not prompted to choose their own maximum.- Fixed conditions in which editing the first or last name of a new
apostrophe-userdid not affect theirslugin the expected way. - Fixed bug: if trashInSchema is in effect, subpages should not have their trash status overridden to match the new parent when their ancestor is moved. This is important when using "Reorganize" with workflow. Additional improvements to better integrate "Reorganize" into the workflow module are separately forthcoming.
- Fixed a bug that prevented
viewpermissions from being given out programmatically in certain edge cases. - The
slugcursor filter now has alaundermethod, for use when marking it safe forreq.query. Thanks to Anthony Tarlao.
Thanks to our customers at Michelin and NPM for making much of the above work possible via Apostrophe Enterprise Support.
Unit tests passing.
Manual regression tests passing.
- Server-side code may now call
apos.notify(req, 'This is a message')to send a message to the logged-in user associated withreq. That message will pop up on the browser and will remain visible until they dismiss it. If the user is not logged in right now, they will see it when they do log in.
You may use %s to interpolate additional string arguments, and you may pass an options object with dismiss: true for a self-dismissing notification. You may also set the type option to error, warn or success for different visual treatments. For example:
apos.notify(req, 'Sorry, you did not win a shiny new %s!', req.piece.title, { type: 'error' });
The API is identical to that for apos.notify on the browser side, except that req must be passed as the first argument. Also the method returns a promise, which resolves when the notification has reached the database. You may also optionally pass a final callback for the same purpose. This is useful when sending a notification just before a task exits the process. The rest of the time you won't need to worry about it.
-
In
2.73.0, an optional second argument,locale, was added to thedateNunjucks filter. As it turns out this was done in a way that could have a knock-on effect on later uses ofdatethat did not specify a locale. This has been fixed and unit tests have been added. Thanks to Fredrik Ekelund. -
The values of fields hidden via
showFieldsare now saved to the database, as long as they contain no errors. This allows you to return to an old setting and discover all of its sub-settings intact. -
By default, Apostrophe deletes old asset bundles from uploadfs (S3, azure, etc.) five minutes after the launch of the site. The assumption is that the deployment of static assets has reached all peer servers and there is no need to keep old assets around. The
uploadfsBundleCleanupoption toapostrophe-assetsmay now be set explicitly tofalseto prevent this, as may be needed if asset bundles are shared between sub-deployments that are made at greatly varying times. -
When
apostrophe-workflowis present, "Batch Commit" and other inappropriate options are no longer offered for groups, which are not subject to workflow.
Thanks to Michelin for making much of the above work possible via Apostrophe Enterprise Support.
Unit tests passing.
Regression tests passing.
- Added in-context editing support, support for the
contextualflag, andskipInitialModalsupport for areas and singletons nested in fields of typeobject. Many thanks to Michelin for making this feature possible through their participation in Apostrophe Enterprise Support. - The
dateNunjucks filter now acceptslocaleas a second argument. Iflocaleis not present andreq.localeis set, that locale is used, rather than the default system locale. Thanks to Tim Otlik. - Removed nuisance warnings about tolerant sanitization.
- When using the
passwordReset: truefeature ofapostrophe-login, you may also set thepasswordResetSubjectoption to a custom subject line for the password reset email message. - The mechanism that sends the password reset request confirmation email has been factored out to the
apos.login.sendPasswordResetEmail(req, user)method, so you can trigger it for your own reasons. This method returns a promise; when that promise resolves the password reset email has been successfully handed off for delivery. Note that the promise will be rejected if the user object has noemailproperty.
Unit tests passing.
Regression tests passing.
- The "apply to subpages" feature for page permissions has been greatly simplified and made easier to understand. There is now just one shared "copy these permissions to subpages now?" dropdown, which applies to ALL current permissions for the current page: "who can view this page," "these users can view," "these groups can edit," etc.
As the help text now properly explains, if you pick "yes" and save page settings as usual, the permissions of all subpages are updated to match on a one-time basis. After that, you can edit them normally for the subpages. This is an action that takes place at "save" time, it is not a setting that is remembered.
This is good for laying down a baseline and then making fine-tuned adjustments per page, which is typical practice.
Previously this choice appeared in several places, including as a highly confusing and visually cluttered dropdown within the list of permissions per user and group. While theoretically this allowed for propagating fine-tuned adjustments to subpages one at a time, in practice users did not understand it, including many enterprise customers who invest significant time in Apostrophe. Therefore a simpler solution is of greater overall value.
-
Regression fix: support for in-context, on-page editing of areas in array fields has been restored.
-
Attempts to save a field of type
objectwith a missingrequiredfield now behave sensibly, you no longer see a spinner forever on a grayed-out page. Note that the use ofrequiredfor the object itself has no meaning because there is always an object; you should make its fields required, or not, as you see fit. -
"Move" and "Trash" operations on widgets now emit the Apostrophe events
widgetMovedandwidgetTrashed. The widget's container div is emitted as the argument to the event.
Unit tests passing.
Regression tests passing.
- The
apostrophe-jobsrunNonBatchmethod no longer crashes if the job-runner function provided does not return an object (for instance, because it takes a callback so its return value does not matter). apostrophe-attachments:listtask lists the URLs of all valid attachments, including all crops in all sizes.arrayfields may be used in therelationshipof a join. Thanks to Anthony Tarlao.- Added missing callback to asset bundle cleanup for cloud deployments, ensuring that the lock is eventually released and the old bundles are eventually removed.
- Fixed documentation for
apos.jobsmethods re: thelabelsoption.
Unit tests passing.
Regression tests passing.
- Moving a page beneath a parent that happens to be considered "not trash" should not automatically cause the child to be considered "not trash" when workflow is in effect, or when the
trashInSchemaflag has been opted into forapostrophe-docs. In these cases the trash flag is just another schema property. This bug led to pages inadvertently becoming live across all locales when moved in the page tree. - The server-side video schema field converter no longer crashes the process if given a
nullproperty, and correctly flags the field as in error if it isrequiredand not present. - Any missing values for join relationships relating to permissions are now handled in a proper migration in apostrophe core, rather than a hack in apostrophe-workflow that adds significant startup time in certain situations.
- Migration completion is now logged.
- UX fix: UI/area controls no longer compete with "Add Content."
Thanks to our enterprise support customers for their support of this work.
Unit tests passing.
Regression tests passing.
- Support for subdirectories of
lib/modules. You must set thenestedModuleSubdirsoption totrueinapp.js. You can then place your modules in nested subdirectories oflib/modules. The names of the parent folders do not matter, and the name of the actual module folder must still match the name of the module.
In addition, when using this feature you may optionally move part of your modules configuration into a modules.js file in each directory. Here is an example:
module.exports = {
'module-name': {},
'other-module-name': {}
};By following through with this approach you can make app.js much shorter. Configuration of Apostrophe modules installed via npm must still be done in app.js.
-
The
apostrophe-html-widgetsmodule now properly concatenates fields to the standard HTML field whenaddFieldsis used with it. -
Fixed a crashing bug when an API was used in an atypical way. Thanks to Max Schlueter.
Unit tests passing.
Regression tests passing.
Recent changes to the markup for buttons broke drag and drop for widgets. This has been fixed.
Unit tests passing.
Regression tests passing.
- When two pieces or pages would have the same slug as the result of an insert or update, Apostrophe automatically appends a unique string. This makes sense for data integrity but as a user experience it leaves something to be desired.
Beginning with this release, if you are editing the title in the piece or page settings editor and apostrophe is making automatic slug suggestions, these suggestions will now include the suffix needed to avoid a conflict. This gives you a chance to see what will happen, and decide to change the title or the slug in a better way. However, you can disable this by setting the deconflictSlugs option of the apostrophe-docs module explicitly to false. If you do, then from now on you will receive a straightforward error message if the suggested slug is in conflict with another slug on the site.
- If you edit the slug directly and try to save it with a conflict, Apostrophe will always report a straightforward error in the editor, requiring you to fix it manually. This makes sense when you are editing the slug yourself, because it means you care about the exact value.
For backwards compatibility and to resolve race conditions, the server will still automatically modify the slug to be unique in the rare event that a conflict arises during the save operation itself.
- A simpler yet even better slug prevention feature, in many ways: all
apostrophe-piecesmodules now accept aslugPrefixoption. For instance, if you set this option topeople-for yourpeoplemodule and toimage-for theapostrophe-imagesmodule, the slugs for your people and the photos of them you are uploading will never be in conflict.
We appreciate our enterprise customers and their support of this work.
Unit tests passing.
Regression tests passing.
- Bug fix: when you attempt to edit a piece that someone else has open in the edit dialog box, you should receive a warning, and the option to take over or leave it alone. This worked, however the "advisory lock" was not released when closing the dialog box. So users saw superfluous warnings. The bug was related to calling
$.jsonCallwith the wrong order of arguments. - Bug fix: a user without permissions to lock a particular document could cause a process restart by attempting to lock it. No inappropriate access was granted.
- When configuring the
csrfoption ofapostrophe-express, you may now pass thecookiesubproperty in order to pass configuration options tores.cookie, such assecure: true. - The jQuery
onSafeplugin now respects the return value of the event handler, allowing the use ofreturn false;in such handlers. Thanks to Fredrik Ekelund. - The Apostrophe
buttonmacro now renders abuttonrather than an anchor tag, except when theurloption is present. Thanks to Fredrik Ekelund.
Unit tests passing.
Regression tests passing.
Apostrophe now allows direct import of unparsed CSS files via import flags of LESS. The best use of this option is to push a CSS file created by a SASS compiler or other LESS alternative.
To push a CSS asset without compiling it as LESS, you may write:
self.pushAsset('stylesheet', {
name: 'bundle',
import: {
inline: true
}
});
Or, if you are pushing assets via the stylesheets option of the apostrophe-assets module, you may write:
'apostrophe-assets': {
stylesheets: [
{
name: 'bundle',
import: {
inline: true
}
}
]
}
The extension of the file may be either .css or .less; either way it is imported with no LESS compilation. Apostrophe will still modify URLs to accommodate the global prefix option, if present.
Unit tests passing.
Regression tests passing.
- In-context editing of areas nested in arrays now works correctly when the widget containing the array has just been added to the page for the first time.
Unit tests passing.
Regression tests passing.
- Promisified all of the apis for migrations, including the option of iterators that return promises, and implemented migrations for old piece and page slugs that have not been deduplicated and thus can block new pages or pieces from taking a slug even though we have logic for this for new pages and pieces.
- In-context editing support for areas and singletons that are schema fields of arrays. Leaves other, noncontextual data alone. Creating and editing entire array items contextually is outside the scope of this change; use an area rather than an array for that. Directly nested arrays are not supported, but you may use an area in an array in a widget in an array, etc.
.jpegfiles were slipping through with that extension. All new uploads will be correctly converted to.jpgand go through the proper sizing process.- The
enableShowFieldsoption was missing some of its logic for fields of typecheckboxes. Thanks to Anthony Tarlao. - A
_titleproperty is now included in attachments returned byapos.images.allandapos.images.first. - When apostrophe cannot fix a unique key error, it is helpful to be able to see the last error, as well as the original one. This helps you figure it out if both a unique slug error and an unrelated unique key error are part of the puzzle. We still throw the original error, but we also attach the last error as a property of it, so you can see both.
- The
apos.areas.fromPlaintextmethod now takes anoptionsparameter. You may set theelproperty to an element name, in which case the markup is wrapped in that HTML element.optionsmay be omitted.
Unit tests passing.
Regression tests passing.
- When we introduced allowedSubpageTypes and allowedHomepageTypes in 2.67.0, we broke support for different schemas in different page types. Those regressions are fixed here.
- The default page type choice offered for a new page is the first type permitted by its parent page.
Unit tests passing.
Regression tests passing.
- The
lateCriteriacursor filter now works properly, allowing special mongodb criteria that are not allowed inside$andto be merged into the criteria object at the last minute. - A noisy warning produced on every page send by the latest version of Bluebird has been silenced.
- Performance: explicitly shut off
sort()for certain cases where we know only one document will be returned. This allows MongoDB to select a more efficient index more often. nlbrNunjucks filter no longer results in double-escaped markup. Thanks to Ulf Seltmann.- The
apostrophe-globalmodule now supports theseparateWhileBusyMiddlewareoption. Iby separate middleware that checks for the lock flag in apostrophe-global even if the regular middleware of this method has been disabled and/or overridden to cache in such a way as to make it unsuitable for this purpose. For normal use this option is not necessary. - Fixes made to further reduce conflicts between sites with
apostrophe-multisite. For instance, theapostrophe-workflowmodule no longer breaks the dashboard. - The home page can now be copied. If you copy the home page, you get a new child of the home page with the same content. Thanks to Tim Otlik.
Unit tests passing.
Regression tests passing.
- Pages can now be locked down with the
allowedHomepageTypesandallowedSubpageTypesoptions, like this:
// Only one type allowed for the home page
allowedHomepageTypes: [ 'home' ],
allowedSubpageTypes: {
// Two subpage types allowed for the home page
'home': [ 'default', 'apostrophe-blog-page' ],
// No subpages for the blog page ("show pages" don't count)
'apostrophe-blog-page': [],
// default page type can only have another default page as a subpage
'default': [ 'default' ]
}These options make it easy to prevent users from creating unintended scenarios, like nesting pages too deeply for your navigation design.
-
Pages now support batch operations, just like pieces do. The initial set includes trash, rescue, publish, unpublish, tag and untag. You can only rescue pages in this way if you are using the
trashInSchemaoption of the docs module, which is always the case withapostrophe-workflow. With the conventional trash can, it is unclear what should happen because you have not indicated where you want each page to be restored. New batch operations for pages can be added in the same way that they are added for pieces. -
Important performance fix needed for those using the
apostrophe-pieces-orderings-bundlemodule to create custom sort orders for pieces. Without this fix it is also possible to get a loader error and stop fetching content prematurely. -
The "revert" button for versions is now labeled "Revert to" to emphasize that it reverts to what you had at the end of that operation, not its beginning. Thanks to Fredrik Ekelund.
- Updated to CKEditor version 4.10.0. The CKEditor build now includes the CKEditor "widgets" feature (not to be confused with Apostrophe widgets). These are essential for modules like the forthcoming
apostrophe-rich-text-merge-tags. apos.areas.richTextandapos.areas.plaintextno longer produce duplicate text. To achieve this, theapos.docs.walkmethod no longer walks through the_originalWidgetsproperty. This property is only used to preserve the previous versions of widgets that the user lacks permission to edit due to schema field permissions. Exploration of this property byapos.docs.walkled to the observed bug.- The browser-side implementation of
apos.utils.escapeHtmlnow works properly.
Unit tests passing.
Regression tests passing.
-
Important fix for MongoDB replica sets: previously we used the
autoReconnectoption of the MongoDB driver by default. From now on, we use it only if the MongoDB URI does not refer to a replica set. The use ofautoReconnectis inappropriate with a replica set because it will keep trying to connect to the node that went down. Leaving this option out results in automatic use of nodes that are up. Also see the apostrophe-db-mongo-3-driver module for a way to use the newermongodb+srvURIs. Thanks to Matt Broadstone of MongoDB for his advice. -
An
apostrophe-filenow has a default URL. The default_urlproperty of anapostrophe-filepiece is simply the URL of the file itself. This allowsapostrophe-fileto be included in your configuration for apostrophe-permalinks; picking a PDF in this way generates a direct link to the PDF, which is what the user expects. Note that if the developer elects to set up anapostrophe-files-pagesmodule that extendsapostrophe-pieces-pages, that will still take precedence, so there is no bc break. -
Clicking directly from one rich text widget into another did not work properly; the toolbar did not appear in this situation. This bug has been fixed. The bug only occurred when clicking in a second rich text widget without any intervening clicks outside of all rich text widgets.
-
Also see expanded notes on version
2.64.1, below, which contained several features missed in the original changelog.
Unit tests passing.
Regression tests passing.
-
Improved Apostrophe's ability to redisplay the appropriate widget, array element, and field and call the user's attention to it when a schema field error is not detected until server-side validation takes place. This addresses problems that come up when fields become
requiredat a later time, and/or data was originally created with an earlier release of Apostrophe that did not enforcerequiredin all situations. Browser-side validation is still preferred for ease of use but server-side validation no longer creates situations the user cannot easily resolve. -
Introduced the
apos.global.whileBusymethod. This method accepts a function to be run while no one is permitted to access the site. The provided function may return a promise, and that promise resolves before the site becomes accessible again. In the presence ofapostrophe-workflowit is possible to mark only one locale as busy. -
By default, the
apos.locks.lockmethod waits until the lock is available before proceeding. However there is now awaitoption which can be set tofalseto avoid waiting at all, or to any number of milliseconds. If the method fails because ofwait, the error is the stringlocked. -
The
apos.locks.lockmethod also now accepts awaitForSelfoption. By default, if the same process invokesapos.locks.lockfor the same lock in two requests simultaneously, one of the two will receive an error. WithwaitForSelf, the second invocation will wait for the first to resolve and then obtain the lock.
Unit tests passing.
Regression tests passing.
- Apostrophe's "search suggestions" feature for
notFound.htmltemplates is now fully baked. It only takes two steps:
- Include an element like this in your
notFound.htmltemplate:
<div data-apos-notfound-search-results></div>
- Set the
suggestionsoption totruefor theapostrophe-searchmodule.
With suggestions: true, this feature no longer requires that you have a /search page, it uses a dedicated route. See the documentation of the apostrophe-search module for more information.
- The
showFieldsoption is now available for checkboxes. The syntax is as follows:
{
"name": "awesomeBoolean",
"label": "Awesome Boolean",
"type": "boolean",
"choices": [
{
"value": true,
"showFields": ["otherField1"]
},
{
"value": false,
"showFields": ["otherField2"]
}
]
}
Thanks to falkodev.
- A useful error message appears if you try to use a
mongodb+srvURL. These are meant for newer versions of the MongoDB driver. You can use them, but you must install the apostrophe-db-mongo-3-driver module first. The error message now explains this, addressing a common question on stackoverflow. - Basic styles added for the most common rich text markup tags when within the bounds of an Apostrophe modal. Thanks to Lars Houmark.
- Fixed UI overlap issue when joining with
apostrophe-page. apos.images.all,apos.images.first, etc. now include_description,_creditand_creditUrlwhen they can be inferred from anapostrophe-imagecontaining the attachment.apos.images.srcsethelper improved. It is now smart enough to limit the image sizes it offers based on what it knows about the size of the original. Thanks to Fredrik Ekelund.- Fixes to CSS asset URL generation to pass validation.
- Performance: eliminated use of
$orMongoDB queries with regard to pages in the trash. MongoDB tests demonstrate that$ne: trueis faster than$orfor our purposes.
Unit tests passing.
Regression tests passing.
- “Promise events” have arrived. This is a major feature. Promise events will completely
replace
callAllin Apostrophe 3.x. For 2.x, all existing invocations ofcallAllin the core Apostrophe module now also emit a promise event. For instance, when thedocBeforeInsertcallAll method is invoked, Apostrophe also emits thebeforeInsertpromise event on the apostrophe-docs` module.
Other modules may listen for this event by writing code like this:
`self.on('apostrophe-docs:beforeInsert', 'chooseASpecialist', function(req, doc, options) {
// Modify `doc` here. You may return a promise, and it will resolve before
// any more handlers run. Then the doc is inserted
});The above code adds a new chooseASpecialist method to your module. This way, the method can be overridden by assigning a new function to self.chooseASpecialist in a module that
extends it, or its behavior can be extended in the usual way following the super pattern.
But, since it does not have the same name as the event (attempting to register a method of the same name will throw an error), it is unlikely that parent class modules and subclass modules will have unintentional conflicts.
See the original github issue for a more complete description of the feature and the reasoning behind it.
Your existing callAll methods will still work. But, we recommend you start migrating to be ready to move to 3.x in the future... and because returning promises is just a heck of a lot nicer. You will have fewer problems.
- Optional SVG support for
apostrophe-attachments. To enable it, set thesvgImagesoption totruewhen configuring theapostrophe-attachmentsmodule. SVG files can be uploaded just like other image types. Manual cropping is not available. However, since most SVG files play very well with backgrounds, the SVG file is displayed in its entirety without distortion at the largest size that fits within the aspect ratio of the widget in question, if any (background-size: containis used). If you have overriddenwidget.htmlforapostrophe-images-widgets, you will want to refer to the latest version ofwidgetBase.htmlfor the technique we used here to ensure SVG files do not break the slideshow’s overall height. - New
apos.templates.prependandapos.templates.appendmethods. Callapos.templates.prepend('head', function(req) { ... })to register a function to be called just after the head tag is opened each time a page is rendered. The output of your function is inserted into the markup. The standard named locations arehead,body,contextMenuandmain. This is convenient when writing modules that add new features to Apostrophe. For project level work also see the named Nunjucks blocks already provided inouterLayoutBase.html. apos.singletonnow accepts anareaOptionsoption, which can receive any option that can be passed toapos.area. Thanks to Manoj Krishnan.- Apostrophe’s “projector” jQuery plugin now respects the
outerHeightof the tallest slideshow item, not just the inner height. apos.areanow accepts anaddLabeloption for each widget type in the area. Thanks to Fredrik Ekelund.- UI improvements to versioning. Thanks to Lars Houmark.
- Button to revert to the current version has been replaced with a label indicating it is current, since reverting to the current version has no effect.
- “Page settings” can now be accessed for any page in the trash via “reorganize.” When
working with
apostrophe-workflow, this is often required to commit the fact that a page is in the trash. - The
uploadfsmodule now has aprefixoption. If present, the prefix is prepended to all uploadfs paths before they reach the storage layer, and is also prepended to URLs. In practice, this means that a single S3 bucket can be used to host multiple sites without all of the uploaded media jumbling together in/attachments. Theapostrophe-multisitemodule now leverages this.
Unit tests passing.
Regression tests passing.
- Introduced a
findWithProjection()method that is added to all MongoDB collection objects. All Apostrophe core modules are migrating towards using this method rather thanfind()when working directly with MongoDB collections. If you are using the standard MongoDB 2.x driver that is included with Apostrophe, this just calls regularfind(). When using the forthcomingapostrophe-db-mongo-3-drivermodule to replace that with a newer driver that supports the full features of MongoDB 3.6, 4.0 and beyond, this method will provide backwards compatibility by accepting a projection as the second argument likefind()did until the 3.x driver was released. Developers wishing to be compatible with both drivers will want to start using this method. Again, this only concerns you if you are querying MongoDB directly and passing a projection to find() as the second argument. And if you don't care about using the 3.x driver, you do not have to change anything. - Various UX improvements and bug fixes to the page versions dialog box. Thanks to Lars Houmark.
- The widget wrapper is updated on the fly with new classes if they change due to edits. Thanks to Fredrik Ekelund.
- When configuring a
datefield, you may pass apikadayOptionsproperty. This object is passed on to thepikadaylibrary. Thanks to Lars Houmark. - The
counts: trueoption forpiecesFiltersnow works properly with joins.
Unit tests passing.
Regression tests passing.
- New "secrets" feature in
apostrophe-usersmakes it easy to hash other "secrets" similar in spirit to passwords. - This feature is now used for password reset tokens, making them more secure.
- Additional joins can now be added to the schema of a widget that extends
apostrophe-pieces-widgets. - Brute force password attacks against an Apostrophe server are now more difficult. Thanks to Lars Houmark.
- Tolerant sanitization of array items while they are still in the editor. This avoids confusion caused by
requiredfields in the array editor. - Error messages now behave sensibly when multiple label elements appear in a field. Thanks to Lars Houmark.
- Fix background color on notification on uploads when file extension is not accepted. Thanks to Lars Houmark.
- If you can't move a widget out of an area, you can no longer move widgets into that area either (movable: false is fully enforced). Thanks to Fredrik Ekelund.
- New browser-side events are emitted during the attachment upload process, and the built-in facility that delays the saving of a form until attachment uploads are complete has been fixed. Thanks to Lars Houmark.
- Fixes to the active state display of array items. Thanks to Lars Houmark.
- Contributor Guide expanded with lots of new information about practical ways to contribute to Apostrophe.
- Contributor Covenant Code of Conduct added to the project. The Apostrophe community is a welcoming place, and now is a great time to lock that in for the future.
Unit tests passing.
Regression tests passing.
- Shallowly clone the required definition in defineRelatedType to prevent yet more crosstalk between instances of apos when
apostrophe-multisiteis used. No other changes.
Unit tests passing.
Regression tests passing.
- Improved support for nested areas and widgets. Apostrophe now pushes the correct doc id and dot path all the way to the page in various situations where this could previously have led to errors at save time.
- The new
apos.locks.withLock(lockName, fn)method can be used to execute a function while the process has the named lock. This ensures that other processes cannot run that function simultaneously. You may optionally pass a callback, otherwise a promise is returned. Similarlyfnmay take a callback, or no arguments at all, in which case it is expected to return a promise. - Cleanup: don't call
server.closeunless we've succeeded in listening for connections.
Unit tests passing.
Regression tests passing.
- Version 2.60.1 broke validation of schema fields which were
required, but blank because they were hidden byshowFields. This is of course permitted,requiredapplies only if the field is active according toshowFieldsor not addressed by anyshowFieldspossibilities at all. Comprehensive unit testing was added for this issue to prevent a recurrence. - Version 2.60.1 also introduced a more subtle issue: if constraints
like
requiredormin, or general improvements to validation such as NaN detection for integers and floats, were added to a widget schema later after content already existed then it became impossible to open a widget editor and correct the issues. Validation tolerance was added for this situation. - When a user edits an area "in context" on the page, the server now reports errors using a path that can be used to identify the widget responsible and open its editing dialog box. A more relevant notification is also displayed. This remains a secondary mechanism. Server-side validation is mostly about preventing intentional abuse. Browser-side validation is still the best way to provide feedback during data entry.
Unit tests passing.
Regression tests passing.
- Fields of type
checkboxesnow play nicely with thelive/drafttoggle ofapostrophe-workflow. - Improved validation of integers and floats. Thanks to Lars Houmark.
- The "Global" dialog box now follows the same pattern as that for other piece types, which means that the workflow dropdown menu is available if workflow is present.
- Options may be passed to the
express.staticmiddleware that serves thepublicfolder, via thestaticoption of theapostrophe-expressmodule. Thanks to Leonhard Melzer. apostrophenow depends onbluebirdproperly and there are no lingering references to the wrong version folodash. Formerly we got away with this because some of our dependencies did depend on these, and npm flattens dependencies. Thanks to Leonhard Melzer.- The new
eslint-config-punkaveruleset is in place, and includes a check for "unofficial dependencies" inrequirecalls that could go away suddenly. fieldClassesandfieldAttributesmay be set on form fields themselves, similar to the existingclassesandattributesproperties that are applied to thefieldset. Thanks to Lars Houmark.- The "Pages" admin UI now includes a "New Page" button, in addition to the usual "reorganize" functionality. Thanks to Lars Houmark.
- Fixed a crash when an
apostrophe-pieces-widgetis configured to always show all pieces viaby: 'all'. Thanks to Aurélien Wolz. - General UI styling improvements and fixes.
Unit tests passing.
Regression tests passing.
- New feature: you can now display counts for each tag, joined item, etc. when using the
piecesFiltersoption ofapostrophe-pieces-pages. Just addcounts: trueto the configuration for that filter. The count is then available in a.countproperty for each value in the array. See creating filter UI with apostrophe-pieces-pages for more information. - New feature: command line tasks such as
apostrophe-blog:generatemay now be run programmatically, for example:apos.tasks.invoke('apostrophe-blog:generate', { total: 50 }). A promise is returned if a callback is not passed. Note that not all tasks are written to behave politely and invoke their callback normally, however most do. This feature is most useful when writing tasks that logically should incorporate other tasks. - Many UX and UI improvements that make the experience more pleasant in subtle and not-so-subtle ways. Thanks to Carsten, Marco Arnone and the prolific Lars Houmark for their contributions. This was an excellent week for Apostrophe PRs.
- The full set of controls for joined items are again available in the chooser, as well as in the browse modal.
- The automatic opening of the admin bar menu on page load can now be configured with the
openOnLoad,openOnHomepageLoad, andcloseDelayoptions. autocomplete="off"for date fields prevents chrome autocomplete suggestions from wrecking calendar UI.- Always remove .apos-global-busy on unlock, even if the transition event never fires. Yes, that is sadly a thing. Prevents the UI from becoming unusable in rare situations (less rare inside functional tests).
- Use
oneto reduce the overhead of .apos-global-busy's transition event handler. We could do more here to reduce overhead, i.e. unhooking it entirely. - Much-improved validation of
min,maxandrequiredfor strings, integers and floats on both the server and the browser side. Thanks to Lars Houmark.
Unit tests passing.
Regression tests passing.
- Widget schemas now support the
defproperty for fields. This always worked for pieces and pages. - Accommodations for functional testing in nightwatch. The currently active Apostrophe modal, and all of its proxies such as its controls that are in a separate div for presentation reasons, now has the attribute
data-apos-modal-currentwhich is set to the class name of the modal. This powers the new apostrophe-nightwatch-tools module, which provides reusable commands and steps that can be used to create test projects similar to our apostrophe-enterprise-testbed. Testing with the enterprise testbed project is a standard part of our release process. - Previously if workflow was in use slugs could not be reused by new pages when the original page was in the trash. This has been addressed; the slug is now deduplicated in the same way that email addresses and usernames of users are when in the trash.
- The infinite scroll feature of
apostrophe-pieces-pagesnow works as documented with the styles provided. The code is also more efficient and scroll events are throttled for performance. Thanks to Lars Houmark. - Various UX fixes, thanks to Lars Houmark and various members of the Apostrophe team.
Unit tests passing.
Regression tests passing.
- Fixed nested widget editing for existing widgets whose modal dialog boxes have been accessed (#1428).
- A clear warning message with instructions has been added for those who are seeing "unblessed" messages due to widget schemas and in-template
apos.areacalls that do not match (#1429). The easiest way to avoid this is to just mark the areacontextual: truein your widget schema so it is edited only on the page. But if you really want to do both, the widget options must match. - The mechanism that automatically makes slugs, paths and other keys unique now gives up eventually and reports the original duplicate key error. This makes it easier to debug your code if you are violating your own custom indexes that feature unique keys. It is possible to make the deduplicator aware of your own own properties that need to be made more unique on inserts if you wish, by implementing a
docFixUniqueErrormethod. Please note: this change is not a regression. Code that formerly never completed its task in this situation will simply report an error promptly rather than retrying inserts forever while degrading your database performance. - A new profiling API has been added: the
apos.utils.profilemethod. This method can be called to report how long code takes to run for later analysis. It does nothing in the default implementation; modules like our forthcoming profiler override it to give feedback on the speed of your code.
Unit tests passing.
Regression tests passing.
- Polymorphic joins have arrived! You may now create joins like this:
{
name: '_items',
type: 'joinByArray',
withType: [ 'apostrophe-blog', 'product', 'apostrophe-page' ]
}When you join with more than one type, Apostrophe presents a chooser that allows you to pick between tabs for each type. Note that apostrophe-page can be included, so you can pick a mix of pages and pieces for the same join.
This feature is useful for creating navigation that may point to a variety of document types, without the need for an array of items with several different joins and a select element to choose between them.
Polymorphic joins work for both joinByOne and joinByArray. Currently they are not available for joinByOneReverse, joinByArrayReverse, or pieces filters. Their primary use case is creating navigation widgets.
apos.images.srcsethelper function added. You can use this function to generate asrcsetattribute for responsive display of an image. Just pass an attachment to the helper:
<img srcset="{{ apos.images.srcset(apos.images.first(data.piece.thumbnail)) }}" />
A src attribute for backwards compatibility is always advisable too.
Thanks to Fredrik Ekelund for this contribution.
-
Fast forms for big schemas are back! The issue with tags has been resolved.
-
A single MongoDB connection may be reused by several
aposobjects for separate sites, a feature which is exploited by the apostrophe-multisite module. Note that this only reuses the connection, it does not share a single MongoDB database. It does allow you to keep potentially hundreds of sites on a single MongoDB server or replica set, as the overhead of multiple logical "databases" is small in MongoDB's modern WiredTiger storage engine. To reuse a connection, pass it to theapostrophe-dbmodule as thedboption. -
Fixed a MongoDB 3.6 incompatibility in the "Apply to Subpages" feature for permissions. Also made this feature available again when removing someone's permissions. We plan further UX work here to make this feature easier to understand and use.
-
UX fix to the "manage tags" dialog box: don't attempt to add an empty tag. Thanks to Anthony Tarlao.
-
Warn developers if they use bad area names.
-
For those deploying asset bundles to S3: the command line task that builds an asset bundle no longer requires access to your production database, although it still needs to start up normally with access to a database in the pre-production environment where you are building the bundle.
-
Refactoring of the trash field deduplication features, in preparation to extend them to pages as well in an upcoming release.
Unit tests passing.
Relevant regression tests passing.
- New
extraHtmlblock inouterLayoutBase.htmlallows yourouterLayout.htmlto add attributes to the outerhtmlelement without the need to completely override the layout. It is a best practice to avoid completely overriding the layout because this maximizes your compatibility with future updates to our admin markup, etc.
Unit tests passing.
- Hotfix for bug in 2.57.0 that broke saving tags. We have reverted the "fast forms" change until the cause is understood.
Unit tests passing.
Functional tests passing.
- Displaying and saving schema-driven forms is much, much faster. This becomes very noticeable with 100 or more fields. With about 250 fields, this formerly took about 4.5 seconds to load or to save such a form on a fast Mac. It now takes about 250 milliseconds.
- Users may re-order the items they have selected via drag and drop when using "Browse" to select pieces, images, etc.
- Prior to this release, asset generation ids were surprisingly short and made up only of digits due to an accidental holdover from an old version. Conflicts were rare, but possible. Asset generation ids are now proper cuids, no conflicts should occur.
- IDs may be added to notifications as a simple way to give other code access to them.
- The
apos.global.addGlobalToDatamethod may now be called with justreq(returns a promise), withreq, callback(invokes the callback), or as middleware (which Apostrophe does by default). This method is handy in command line tasks and other places where middleware does not run andreq.data.globalis not populated by default.
Unit tests passing.
Functional tests passing.
- Security: numerous issues formerly flagged by the new
npm auditcommand have been addressed. We are now using a maintained branch of lodash 3.x to keep bc while addressing security (many thanks to the Sails team). We are also using LESS 3.x, which has caused no issues in our testing and corrects security concerns with LESS 2.x. Numerousnpm auditsecurity reports regardingimageminmodules were addressed by removingimageminfromuploadfsitself, however you may opt into it via the newpostprocessorsoption ofuploadfs. As of this writing, onenpm auditcomplaint remains: theazure-storagemodule needs to update a dependency to address a possible vulnerability. You may mitigate this issue by not using theazurebackend ofuploadfswith Apostrophe until it is resolved upstream. - Many UI enhancements when choosing, browsing and managing items which reduce user confusion. For instance: moving items up and down in a selection no longer refreshes the entire list and forces the user to scroll down again. Trashed pages are easier to distinguish in "reorganize." "More" dropdown for pieces is again fully visible when clicked. Placeholder helpers make the search field for joins easier to understand. Chevrons added to various select elements which were difficult to identify as dropdowns before.
- Deeply nested areas now save properly. Formerly in certain situations the same widget might be duplicated.
apos.tasks.getReqnow supplies an emptyreq.dataobject for easier use with code expecting an Express request, Apostrophe-style.- Bedeviled by case-sensitive sorting? The
sortify: trueproperty forstringschema fields is now documented and automatically creates a database migration to ensure it is available for your existing data as well. When used, this flag ensures that anysort('fieldname')call for that field in Apostrophe is case-insensitive, ignores punctuation and otherwise behaves as end users expect.
Unit tests passing.
Relevant functional tests passing.
- Reverted change to date formatting.
momentwill produce warnings again, but dates will not be a day old in some time zones, which is more important. We are working on a better fix for this problem.
Unit tests passing.
Relevant functional tests passing.
apos.migrations.eachAreano longer crashes the stack when iterating over a large number of documents without areas.
Unit tests passing.
Regression tests passing.
- Security fix: uploaded images "in the trash" were still accessible at the same URL in most sizes. This has been corrected. As documented, the only size that now remains accessible is the
one-sixthsize, and this choice can be changed or eliminated entirely. This bug did not affect other file attachments, such as PDFs.
As always, be sure to run the apostrophe-migrations:migrate task. This will make sure the permissions of your files are correct. Harmless warnings may appear for those that were already correct.
-
The
apostrophe-attachments:migrate-to-disabled-file-keyandapostrophe-attachments:migrate-from-disabled-file-keyhave been added for the convenience of those using thedisabledFileKeyoption touploadfsto rename disabled files in a cryptographically sound way rather than changing their permissions. These are relevant only with thelocalstorage option ofuploadfs, since since the option is neither available nor necessary for S3, and is mandatory for Azure from the beginning. -
Although technically part of UploadFS 1.9.0, we'd like to note that the
azurestorage backend is now available and can be part of youruploadfsconfiguration for theapostrophe-attachmentsmodule. -
Server-side modules can now extend the buttons available in the "manage" modal of pieces without overriding templates, similar to the way they are extensible in the "edit" modal.
-
UX fixes.
-
Cropping an image through Apostrophe now works when attachments are stored in S3, Azure, etc.
-
Date parsing does not generate
momentjswarnings. -
Overrideable block in the outerLayout for the context menu.
-
The
apostrophe-soft-redirectsmodule now accepts astatusCodeoption, which you may change to301to use hard redirects. Thanks to Leo Melzer.
Unit tests passing.
Regression tests passing.
-
Contextual editing of pieces found in a
widget.htmltemplate saves properly, as does contextual editing of a nested area added to the page for the first time. -
Previously executed migrations are remembered in a collection that persists, not just in a cache, avoiding extra work which could be extensive in a large database. Migrations are still required to be idempotent (they should detect whether they have any work to do, and do no harm if they are not needed again for a particular document).
-
apos.migrations.eachWidgetnow delivers an accuratedotPath, which is crucial for the use ofapos.docs.db.updatewith$set. No standard migrations in Apostrophe were using the feature until now.
Unit tests passing.
Regression tests passing.
- A bug in the recently introduced
apostrophe-soft-redirectsmodule caused crashes in cases where the context page or piece had no_urlproperty... which is an unusual situation (how did you get there exactly? Overrides are clearly involved), but it can happen in customized projects. Fixed.
Unit tests passing.
Regression tests passing.
- A bug in Chrome 66 causes problems when selecting images in Apostrophe's media library. This bug did not appear before Chrome 66 and does not appear in other browsers. We resolved it by migrating to the use of the CSS grid feature in compatible browsers.
Unit tests passing.
Regression tests passing.
- Several performance improvements. In situations where Apostrophe formerly made expensive "matching nothing" queries, Apostrophe now either skips the entire query or uses an efficient query for a nonexistent
_id, depending on whether the method in question has the right to cancel the entire operation. - Resources released more completely by
apos.destroy, which can now satisfy the expectations ofmocha5.x (no timeouts left active, etc). This was done by adding adestroymethod touploadfs. rangeschema fields behave better when there is no existing value.- Save operation of a modal now triggers the global busy state to prevent race conditions and other unwanted behavior.
- Global busy state can now be pushed and popped, and modals utilize this, so that a modal can be used to gather information during the
saveContentmethod of another modal.
Unit tests passing.
Regression tests passing.
- Do not send X-XSRF-TOKEN headers in an OPTIONS request. This change was mistakenly left out of the 2.52.0 release.
- The named anchor
maincan now be overridden via themainAnchornunjucks block. - The
npmRootDiroption can be used to cause Apostrophe's module loading mechanism to seek npm modules in a location other than that specified byrootDir(or the project root). The newlocalesDiroption ofapostrophe-i18ndoes the same for localization. This makes it possible to userootDirto specify an alternate location for everything else, i.e. the parent ofpublic,data,lib/modules, etc. A necessary accommodation for the evolvingapostrophe-multisitemodule. - Raw HTML widgets now offer help text out of the box.
- The
express.staticmiddleware now runs before theapostrophe-globalmiddleware and other "standard" Apostrophe middleware. - Your own module-level
expressMiddlewareobject can specify{ when: 'beforeRequired', middleware: function(req, res, next) { ... })to run before the required middleware as well. Note that this means no sessions, no users and no body parser. Most of the time you'll want those things. - CSS adjustment to tabs in modals so they don't scroll in Firefox.
- Dropzones for empty areas are easier to drop onto.
Unit tests passing.
Regression tests passing.
- No more 404's when slugs change for pages and pieces. Apostrophe now automatically implements "soft redirects" to the new URL of a page or piece. This is a major SEO improvement, with good support for any page or piece with a
._urlproperty. Note that this feature "learns" URLs over time as the pages and pieces are actually accessed, so if you decide to test it, remember that you must access the old URL at least once before you change it for the test. This feature can be disabled, if you really want to, by setting theenableoption of theapostrophe-soft-redirectsmodule tofalse. - Indexed queries on the
parkedIdandadvisoryLock._idproperties. The lack of indexes for these properties could lead to full collection scans, so this is a significant performance boost on large databases. - Apostrophe's anti-CSRF forgery X-XSRF-TOKEN header is no longer sent as part of an OPTIONS request, or as part of a cross-domain request. In the first case, cookies cannot be set by the server anyway, and in the second, we are communicating with a server that cannot see our session to verify it. In both cases, sending the headers was causing configuration headaches for developers. Thanks to Priyansh Gupta.
- A UI bug fix: the recently added "clone" button for widgets is no longer displayed for singletons, or for areas whose
limithas been reached. Also, thecloneable: falseoption can be used to disable this feature for a particular area. - UI bug fix: no more conflicts between the "Add Content" menu and the up/down/remove/etc. buttons for widgets.
- Clearer warnings and error messages.
Unit tests passing.
Regression tests passing.
- Do not crash when updating a doc if widgets exist but
_originalWidgetdoes not. This can happen in workflow scenarios where Apostrophe'sfindis bypassed. - Accommodations for the forthcoming
apostrophe-optimizermodule.
Unit tests passing.
Regression tests passing.
- Widget fields may now have a
permissionproperty. If present, the user must have the named permission (such asadmin), or they will not see that particular field in the editing dialog box. This is useful when a widget should be authorable by most users but has a sensitive field that should be restricted to a smaller group of users. Note that this feature already existed for schema fields of pieces and pages. - Apostrophe again allows a named pipe to be specified via the
PORTenvironment variable, for compatibility with Windows. Thanks to Jørgen M. Skogås for this fix. - Apostrophe's default settings for the
bodyParseroption are now generous enough, in the case of JSON request bodies, to cover all reasonable editing scenarios in Apostrophe. This change also benefits theapostrophe-headlessmodule. - When Apostrophe must generate a
pathfor a new page, it will look at the providedslugbefore it looks at the providedtitle. This is useful when titles in an import are of poor quality but slugs are unique. Prevents unnecessary numbered suffixes after both slugs and paths. - The dropdown menu to add a widget no longer has a conflict with the hover menu offering widget controls such as "up," "down," etc. The hover menu does not appear while the dropdown menu is open.
Unit tests passing.
Regression tests passing.
- Clone button for widgets in areas, to save time when editing.
- New features for displaying the titles of array items when editing fields of type
array.titleFieldmay now use dot notation. In addition, if that isn't enough, you may uselistItemTemplateto point to an alternative to the standardarrayListItem.htmltemplate, which you may use as a reference. In addition, bothtitleFielddot notation and the customlistItemTemplatehave full access to joins. Be sure to use cross-module include syntax if you don't want to put the template inlib/modules/apostrophe-schemas/views. For instance, you may writelistItemTemplate: 'my-module-name:listItemTemplate.html'. - Bug fix: modals are the right height when jQuery 3 is in use.
- CSS class added to the
h4that displays the title in anapostrophe-imageswidget, for your CSS styling convenience. Thanks to Gareth Cooper.
Unit tests passing.
Regression tests passing.
- New password reset feature. You will need to configure
apostrophe-emailand opt into this feature. See the new Apostrophe password reset HOWTO. - Significant performance boost to the "reorganize" modal in situations where numerous pages are in the trash when using the
apostrophe-workflowmodule. - If widget ids are not provided when inserting new documents they are automatically generated. This makes apostrophe-headless easier to use.
Unit tests passing.
Regression tests passing.
- New
colorandrangeschema field types.colorprovides a color picker field allowing values compatible with CSS, etc.rangeprovides an<input type="range">element and respectsminandmaxoptions. - New
apos.utils.log,apos.utils.info,apos.utils.debug,apos.utils.warnandapos.utils.errormethods. These are now used consistently throughout Apostrophe core, both in the server and in the browser. On the server, these methods wrap the corresponding methods of aloggerobject and you can inject your own via theloggeroption of theapostrophe-utilsmodule. By default a logger object that wraps theconsoleobject is created. For convenience, if your logger has nologmethod,apos.utils.logwill calllogger.info. This allows many popular loggers likewinstonto be used without modification "out of the box." modulesSubdiroption to specify subdir where local modules come from, overridinglib/modules. Useful when more than oneaposobject exists in a project.- Major speedup to parked pages. Also eliminates spurious warnings about inefficient joins at startup.
- Refactored autocollapse behavior of admin bar into its own method for easier overrides.
- CSS fixes for improved usability.
Unit tests passing.
Regression tests passing.
-
Developers now have the option to use jQuery 3. To enable jQuery 3, set the
jQueryoption of theapostrophe-assetsmodule to the number3. We have packaged specific versions of jQuery 3 and jQuery UI which are known to be compatible with and tested with Apostrophe's UI, and we plan to use these in our own projects going forward. We will be making this change in the apostrophe boilerplate project. Of course Apostrophe's UI remains compatible with the older version of jQuery that loads by default. There is no bc break. -
When you join with pages, by using the virtual doc type
apostrophe-page, the user is now invited to choose a page via a version of the reorganize dialog box, which has been made more user-friendly for this purpose. Autocomplete is still supported too. -
The reorganize dialog box is more pleasant to use. This dialog will continue to evolve to offer more of the functionality found in the "manage" dialog boxes for piece types.
-
The page parking mechanism has been overhauled and improved. From now on, it is our recommendation that you set a unique
parkedIdfor each parked page you configure forapostrophe-pages. This ensures that even if you change the slug in the configuration of the parked page, Apostrophe will still be able to understand that the page already exists and a new one should not be inserted. This is especially critical if usingapostrophe-workflow, since you might decide to add or change locale prefixes at some point. -
The database connection keepalive mechanism now uses a query against an empty collection, rather than a server status call that the database user might not have permission to make.
-
The
apos.utils.cssNamehelper now preserves double dashes, as they are a common feature in modern CSS frameworks. -
There is now an
apostrophe-areas:widgetBase.htmlfile which can be extended block by block in a project-levellib/modules/apostrophe-areas/views/widget.htmlfile. New overrideable methods have also been added to simplify adding custom classes programmatically to the wrapper and the widget itself without overriding any templates. -
It is now possible to configure select elements (we do not recommend more than one) to be displayed inline with the other widget controls, i.e. up, down, delete, etc. The back end of this is left to the developer, however you can check out the still-evolving apostrophe-personas module for an example. This feature is primarily meant for modules like
apostrophe-personasthat impact all widgets in a general way.
Unit tests passing.
Regression tests passing.
- Attachment fields now save properly when directly part of the schema of a widget. A bug was introduced in version 2.42.0 when the
lengthproperty was added to attachments. A fix made long ago toapos.utils.clonePermanenton the server side was also needed on the browser side.
Unit tests passing.
Regression tests passing.
-
The "Copy" button of pieces now copies areas that do not explicitly appear in the schema, and works correctly when an
apostrophe-piecesmodule is setcontextual: true. Overrideable methods are provided for those who need to copy more than schema fields and top-level areas. We do not copy every property by default because this could have unforeseen consequences; we copy only what is in the schema, plus top-level areas because these have always been supported without an explicit schema in templates. -
It is now possible to secure widget properties so that they are not visible to end users if you do not choose to output them in the markup. To do that, set the
playerDataoption of your widget module tofalse, or to an array of properties that should be visible in thedataJSON attribute so that they are passed to theplay()method. Normally widget properties are public information, intended for display, but this technique is useful if you have ausernameandpasswordfor use in fetching an external feed in a server-sideloadmethod, for instance. Note that to allow widget editing to function, everything is still passed indataif the user has editing privileges for the widget. So if you seek to verify this feature, be sure to check as a logged-out user, or a user without editing permissions for that content. -
It is now easy to override the
fieldsetmarkup for Apostrophe schemas. Just copylib/modules/apostrophe-schemas/views/fieldset.htmlto your project-level version of that path and edit it. However, please note that you must continue to have an outer wrapper element with the given attributes. -
Apostrophe's codebase now passes
eslint. In the process many cases of callback errors being ignored were fixed, as well as global variable leaks. -
Apostrophe's
apos.locks.lockandapos.locks.unlockmethods now support promises.
Unit tests passing.
Regression tests passing.
- The
apostrophe-cachesmodule has better, clearer documentation and it now supports promises. - All modules can now conveniently send email using Nodemailer. The new
emailmethod of all modules renders a template in that module'sviewsfolder, exactly as you would hope it would, and also automatically generates a plaintext version for the occasional user who does not view HTML email. The automatically generated versions include links properly. - Extending
apostrophe-images-widgetsand other pieces widgets is easier. If your widget name doesn't correspond to the kind of piece you are displaying, a helpful error appears explaining that you need to setpiecesModuleName. Adding fields to these widgets now behaves reasonably. Also, if you add fields toapostrophe-imagesorapostrophe-filesat project level, this now behaves as expected too. - A locking mechanism has been added during the movement of pages in the page tree. This prevents rare race conditions that could previously have resulted in duplicate page ranks, although the design of the page tree is such that more serious consequences were always avoided.
- Text justification options for ckeditor are now standard in our build of ckeditor. Of course you still need to configure
sanitize-htmlproperly when using them. - Any widgets module may now specify a
wrapperTemplateoption. That template is rendered instead of the standardapostrophe-areas:widget.htmltemplate, and can useextendsand override blocks found in that template. This is useful if you need to set attributes of the outer wrapper element of the widget. - The migration added in 2.43.0 to address file permissions for existing attachments in the trash has been greatly accelerated, helpful on large sites.
- Better error messages for
minandmaxoptions of some schema field types; provisions for expanded error messages in general. - For those using the
testModuleoption to test their own npm modules in the context of Apostrophe, a default shortname is automatically provided. - Fixed missing space in admin bar markup, thanks to arlecchino.
Unit tests passing.
Regression tests passing.
- Apostrophe's AJAX filter features for
apostrophe-pieces-pagesnow support "Load More" buttons and infinite scroll.
To add a "Load More" button:
- Wrap a new element inside your data-apos-ajax-context element around the content that makes up the current "page" of results. This should not wrap around filter links or the "Load More" button itself.
- Give that new element the
data-apos-ajax-appendattribute. - Add
append=1to the query string of your Load More button. Example:
{% if data.currentPage < data.totalPages %}
<a href="{{ data.url }} | build({ page: data.currentPage + 1, append: 1 })">Load More...</a>
{% endif %}
To progressively enhance this for infinite scroll, add a data-apos-ajax-infinite-scroll attribute to the button.
Note that we do this via progressive enhancement of a "Load More" button so that Google can still reach and index all of the pages (SEO).
- Attachment schema fields now respect the new
fileGroupandfileGroupsproperties. IffileGroupis set toimages, then only image types (GIF, JPEG, PNG) are accepted; if it is set toofficeonly typical business file types are accepted. Note that we have always rejected files that didn't appear on the list for either type. You can also specifyfileGroupsas an array. fileGroup: 'image'is now configured by default forapostrophe-images, as was always intended but incorrectly implemented in the past.- Attachment schema fields now respect the new
extensionandextensionsproperties. The former is handy if you only want to allow one extension, the latter if you want to allow more than one. The extensions must be those specified forfileGroupsin the default configuration ofapostrophe-attachmentsor your override of it (all lower case; JPEG isjpg; no period). - The
addDocReferencesmigration has been parallelized, as this one-time migration can be time-consuming on a large site. - Broken
lesscalculation fixed, thanks to Antoine COMBES.
Unit tests passing.
Regression tests passing.
-
When a "file" or "image" is moved to the trash, the attachment in question now becomes inaccessible. This is particularly important to stop access to obsolete PDFs, which Google loves to access. If the file or image is removed from the trash, the attachment becomes available again. In the case of images, the 1/6th size remains available by default to provide preview when viewing the trash. If the same attachment is referenced by more than one doc, which can happen due to "Copy" operations or
apostrophe-workflow, it remains available until all such docs are in the trash. -
Parked properties are no longer editable in page settings. Since every site restart always wiped them out anyway, this is a bug fix, not a truly new behavior. With this change, you can finally set
type: 'home'whenparking the home page, and removehomefrom your page types dropdown. -
The
apostrophe-jobsmodule now offers arunNonBatchmethod, which is useful for long-running operations that don't involve iterating over many instances of the same type of object. -
Improvements to background image positioning for images widgets.
-
A block has been added to override the
langattribute easily. Thanks to Ayho. -
The
imgAltblock can now be used to conveniently override thealtattribute of images when overridingwidget.htmlforapostrophe-images-widgets. Thanks to Raphaël DiRago. -
The
requiredoption now works properly for fields of typearray(there must be at least one item in the array). -
Improved error messages for unblessed widget schemas. These are usually related to a widget that is no longer in the page template but appears in the database.
-
A UI bug that caused tabs to become invisible when returning from nested dialog boxes has been fixed.
-
Filters for "select" fields now default to "no opinion," rather than the default choice. This is the normal behavior for other field types.
-
Even more promise support!
apos.attachments.insert,pieces.trashandpieces.rescueall return promises if no callback is given. -
A YouTube embed unit test was removed to ensure consistent results in Travis CI, which is once again in routine use.
Unit tests passing.
- Use of a capitalized filename that should have been lowercase in a
requirebriefly broke Apostrophe's initialization on Linux. We are correcting this by reinstating CI in a Linux environment.
Unit tests passing.
Regression tests passing.
- Promises have landed in Apostrophe. Calling
toArray,toObject,toDistinctortoMongoon an Apostrophe cursor without a callback will return a promise. That promise will resolve to the expected result.
In addition, docs.insert, docs.update, pieces.insert, pieces.update, and pages.insert will all return a promise if invoked without a callback.
These are the most frequently invoked functions in Apostrophe that formerly required callbacks.
As always with promises, be sure to catch errors with .catch() at some level.
Note that the await keyword can now be used with these methods, as long as you're running Node.js 8.x or newer or using Babel to provide that language feature.
-
Apostrophe's custom
SplitCKEditor toolbar control now works correctly in 2.x. You can give your users theSplitcontrol to allow them to break up a large rich text widget in order to insert other types of widget "in the middle." Note that the control name is now capitalized to match the way other CKEditor toolbar buttons are named. -
You may now specify
_url: 1or_nameOfJoin: 1in a projection when using Apostrophe'sfind()methods. Native MongoDB projections naturally can't see these "computed properties" because they don't live in the database — they are computed "on the fly" after documents are fetched. However, Apostrophe now automatically adds the right underlying fields to the projection.
Only _url and the names of joinByOne or joinByArray fields are supported. It does not make sense to use a projection on people to locate IDs that are actually attached to products via joinByOneReverse or joinByArrayReverse.
This feature does not conflict with legitimate uses of MongoDB projections because Apostrophe discards all properties beginning with _ when writing to the database, except for _id.
-
The
lengthproperty of an Apostropheattachmentobject is now correctly populated with the original file size. Thanks to David Keita. Note that images are also made available in many scaled sizes. Also the original may be replaced with a correctly rotated version, in which caselengthwill not match. So the most useful scenario for this property is likely to be in working with office formats, especially PDF which can sometimes be very large. -
Fixed bug in the
isEmptymethods for areas and singletons. Thanks to David Keita.
Unit tests passing.
Regression tests passing.
- The new
apostrophe-jobsmodule, part of the core of Apostrophe, provides a progress meter mechanism and the ability to stop long-running user-initiated operations, such as batch operations on pieces. See the jobs module documentation. You can also refer to the pieces module for examples if you wish to use this for your own long-running user-initiated operations. - Batch operations now have more robust support for "select everything." A number of bugs related to multiple selection of pieces have been fixed in a refactoring that made this code much more maintainable and predictable.
- The option of pushing an asset of type
template, which never worked in 2.x and was never used by Apostrophe, has been removed for clarity. Our preference is for rendering assets on the server side dynamically when needed, rather than pushing many templates into the DOM on every page load. - An
.editorconfigfile has been added. Thanks to Fredrik Ekelund. - Parking a page only pushes permanent properties.
_defaultsand_childrenshould never have been in the database; they are of course still interpreted to decide what should happen, but the properties themselves did not belong in the database. (You may need to write a migration if they are already there and this is causing issues for you.) - Scrolling UI behavior of pieces improved; various other UI touch-ups. Thanks to Fredrik Ekelund.
newBrowserCallshelper forpushmodule can be used when you want JavaScript calls queued up withreq.browserCallto be executed in an AJAX update of just part of a page.- Fixed bugs affecting access to the published/unpublished batch operations and similar.
Unit tests passing.
Regression tests passing.
- Support for "select everything" when managing pieces. Once you check the box to select everything on the current page, you are given a secondary option to select everything that matches your current criteria. This works both when choosing pieces for widgets and when working with batch operations like "trash" or "rescue."
- Fixed various bugs affecting combinations of "select all on page", the chooser and working with images.
- Improvements to batch operations on pieces. The
requiredFieldproperty is checked correctly, and the newonlyIfproperty allows for passing a function that accepts the doc type name and decides whether the button should appear. Multiword action names are properly camelcased. New "success" and "dataSource" options tobatchSimpleallow for carrying out additional operations afterward as well as gathering input independently at the start. And batch operations are composed late so that other modules can add them. - The
self.apiandself.htmlmethods ofapostrophe-contextandapostrophe-modalnow support a syntax for making cross-module API calls, just like templates. - Addressed moog versioning issue with latest npm that caused errors about "synth.instanceOf" not being found depending on the state of your npm cache.
Unit tests passing.
Startup-related regression tests passing.
- The
APOS_MONGODB_LOG_LEVELenvironment variable can now be set todebug,infoor anything else supported by the MongoDB driver'sLogger.setLevelmethod. This is helpful for debugging database issues at the lowest level.
Unit tests passing.
Regression tests passing.
- Factored out a
getBaseUrlmethod forapostrophe-pages, allowing overrides of this that pay attention toreq. - Report
pageBeforeSenderrors and failures to load the global doc properly, don't silently tolerate them. - Documentation corrections. Thanks to Frederik Ekelund.
Unit tests passing.
Regression tests passing.
- Easier access to options. Introduced the
getOptionmethod to all modules. Callingself.getOption(req, 'sizes.large')from your module's server-side JavaScript code, or justmodule.getOption('sizes.large')from Nunjucks, will return the value ofself.options.sizes.largefor that module. You may also pass an array of keys, i.e.module.getOption([ 'sizes', 'large' ]). This method is tolerant, it returns undefined if any part of the path does not exist. See also the new apostrophe-override-options which extends this feature to support customizing the returned value for any option based on the current page type, page settings, piece settings and locale. * Helpful warning when maximum area/widget loader recursion level is reached. Always use projections when adding joins to your schema to avoid a performance hit due to runaway recursion. - New
disabledTypesoption toapostrophe-pages, primarily for use withapostrophe-override-options. - Fixed UI bug relating to area menus at the bottom of the page.
- Fixed bug that caused a crash when invalid usernames attempted to log in. Thanks to Arthur.
Unit tests passing.
Regression tests passing.
- Various schema field validators for required fields no longer crash on the browser side if a property is nonexistent, as opposed to being the expected empty string.
- Buttons for editing pieces widgets now use less confusing language.
- Accommodations for the
apostrophe-headlessmodule (arriving later today), including factoring out certain login-related and piece-related functionality to separate methods in order to make it easier to introduce RESTful APIs for the same features. - Unit tests no longer drop the entire test database between suites; instead they drop the collections. Also the unit test timeout can be set via an environment variable. This accommodates testing against various cloud databases with security that precludes dropping entire databases.
- Lots of new content in the README to get folks who haven't been to the documentation site yet a little more excited.
Unit tests passing.
Conflict resolution and template extension-related regression tests passing.
-
The conflict resolution feature, which helps users avoid conflicts in which neither is successfully able to save content reliably by explaining that two users are editing the same doc and offering the option of taking control, can now be disabled by setting the
conflictResolutionoption of theapostrophe-docsmodule explicitly tofalse. We do not recommend the use of this option in normal practice, however it has valid applications in automated testing. -
Recently a bug was introduced in which extensions other than
.htmlor.njkdid not work inincludestatements, etc. in Nunjucks templates unless the file in question existed in the project-level version of the module including it. The full cascade of template folder paths is now supported for these explicit extensions, including searchingviewsFolderFallback.
Unit tests passing.
Piece- and schema-related regression tests passing.
- Filters are now available for schema fields of type
integer. You can configure these for the manage view, or for pieces-pages, exactly as you would for other field types. Previously this feature existed but did not function properly, so this is a patchlevel release rather than a minor version bump. - Previously, when viewing pieces in the trash, the batch operation button initially read "Trash Items" rather than "Rescue Items." It did not match the selected operation in the select element, and did not perform the needed operation of rescuing items unless you switched operations and switched back again. This has been fixed.
Unit tests passing.
Regression tests passing.
- New feature: you may now use the
.njkfile extension in addition to.htmlfor your Nunjucks templates. In order to maximize the usefulness of this feature in the context of existing Apostrophe code,.njkis still checked for even if.htmlwas specified when calling therendermethod..njkis a convention adopted by the Nunjucks community and is supported by some syntax highlighters. - Bug fix: drag-and-drop reordering and movement of widgets is once again functional. (The arrows worked all along.)
- Bug fix: drag-and-drop targets for widgets residing in areas nested in other widgets now appear and function properly.
Unit tests passing.
Regression tests passing.
- If an oembed provider responds with an HTTP error and a response that is not parseable as XML or JSON, Apostrophe no longer crashes (this fix is actually in the oembetter npm module). This fixes crashes on non-embeddable YouTube videos.
- If the oembed provider issues a 401 or 404 error, a relevant error message is given. Otherwise the generic error icon is still given.
Unit tests passing.
Regression tests passing.
- Dragging and dropping will now automatically scroll the "reorganize" dialog box.
- Attempts to drag a page above or below the "Home" page in "reorganize" no longer cause a restart. Also, the interface rejects them gracefully.
- Attempts to drag a page below the trashcan are rejected gracefully.
- When
trashInSchemais active, the "traditional" trash can sorts below "in-context" trash, and the traditional trash can receives the special label "Legacy Trash" to reduce confusion. - When on page two (or higher) in the "manage" view of pieces, performing a text search now correctly resets to page one.
- Throw an error at startup if a forbidden schema field name is used in
addFieldsconfiguration. For instance,typeis forbidden for widget schemas, whiledocPermissionsis forbidden for doc type schemas, and_idis forbidden for both. Note that field names liketitlethat are already in the schema are not forbidden because re-adding a schema field replaces it, which is often done to change the label, etc. So we'll be adding more documentation about these to help developers avoid surprises if their intention was an entirely new field.
Unit tests passing.
Regression tests passing.
- Spurious conflict resolution warnings for pieces fixed.
- Notifications are spaced properly, and in the upper right corner as intended, on all screens.
- Reorganize feature: upgraded to jqtree 1.4.2. Regression testing found no bc breaks.
- A debugging convenience: the
log(true)cursor filter logs MongoDB criteria objects resulting from the cursor in question to the console.
Unit tests passing.
Regression tests passing.
- You may now set the
skipInitialModaloption for any widget module totruein order to avoid displaying the editing dialog box when the widget is first added. This makes sense if the widget has a useful default behavior, or consists of a contextually editable rich text sub-widget with a "style" select element you might or might not need to set every time. - Fields in Apostrophe's schema-driven forms now receive globally unique
idattributes, and theforattributes oflabelelements now reference them properly.
Unit tests passing.
Regression tests passing.
- Intermittent "not blessed" errors when editing joins in widget schemas have been corrected by blessing all widget schemas at page serve time, just as we already bless all doc type schemas at page serve time. Blessing them when the individual routes fire is problematic because of probable race conditions with sessions.
Unit tests passing.
Regression tests passing.
-
apos.areas.isEmpty(data.page, 'body')will now tell you if that area is considered empty (it contains no widgets, or the widgets consider themselves empty). -
The new
controlsoption may be passed to any widget, viaapos.singletonor via the configuration for that specific widget type in anapos.areacall. In this example, the widget cannot be removed, cannot be moved, and has its controls positioned at the upper right instead of the upper left:
{{
apos.singleton(data.page, 'footer', 'apostrophe-rich-text', {
controls: {
removable: false,
movable: false,
position: 'top-right'
}
}
})
}}
The position suboption may be set to top-left, top-right, bottom-left or bottom-right.
The removable and movable suboptions are primarily intended for singletons.
-
By popular demand, the
insertandupdatemethods of pieces now pass the piece to their callback as the second argument. -
Better CSS reset for Apostrophe's admin UI.
-
callOneadded for convenience when you want to invoke a method normally invoked bycallAllin the same way, but for only one module. Thanks to Arthur. -
If an attachment does not exist,
apos.attachments.urlno longer results in a template error page. Instead a fallback icon is displayed and an error message is logged. Developers should still always check whether attachments and joined objects still exist in their templates. Thanks to Raphaël DiRago. -
Notifications within modals move to lower right corner of modal for readability.
-
Cleaned up font paths.
-
Accommodations for the latest release of the separately published apostrophe-workflow module.
Unit tests passing.
Regression tests passing.
A bug was fixed that prevented nested area editing. The bug appeared in version 2.34.0.
Note that editing an area on the page has never been possible when it is part of the schema of an array field. That is not a new issue. It is being tracked and discussed. Today's fix was for a regression that impacted all nested areas.
All tests passing.
Fixed a bug that generated an error message regarding conflict resolution when attempting to edit an area inside a piece editor dialog box.
All tests passing.
Fixed an issue impacting unit test harness only. It didn't come up initially because it had to do with automatically creating test/node_modules, which existed our dev environment.
No code changes outside of tests.
All tests passing.
- Conflict resolution has been added to Apostrophe. When two users attempt to edit the same document, whether "in context" on the page or via a dialog box, Apostrophe now makes the latecomer aware of the issue and gives them the option to take control of the document after warning that the first party could lose work.
Since the first user may have simply abandoned their work, Apostrophe also indicates how long it has been since the first user last made a change.
If the same user attempts to edit a document in two tabs or windows, something very similar happens, although the message is different.
-
In a related change, Apostrophe does not begin attempting to save an area on the page until the user interacts with it for the first time. This fixes many commonly reported frustrating situations in which one user is editing and the other is logged in but merely looking at the page, creating a ping-pong exchange of save requests.
-
Apostrophe's unit tests have been restructured so that a single test file can be run conveniently, via
mocha test/docs.js, for instance, and there is no longer a need for us to updatetest/test.jsevery time a test is added. Also, the unit tests use the sameapos.tasks.getReqandapos.tasks.getAnonReqmethods that are used by real-life command line tasks, which provide a more faithful simulation of an Express request object and one we anticipate extending as needed.
All tests passing.
- Fixed potential crash in version pruning mechanism.
All tests passing.
- The login page can be disabled via the new
localLoginoption of theapostrophe-loginmodule. Set it explicitly tofalseto disable the login URL completely. - Refactoring: the
apostrophe-loginmodule now has anafterLoginmethod which takes care of invoking theloginAfterLogincallAll method on all modules that have one, and then redirecting appropriately. This code was factored out to make it easier to use in the new apostrophe-passport module, which allows the use of almost any Passport-based strategy, such as Facebook login, Google login, Github login, etc. apos.users.ensureGroupnow delivers the group to its callback as the second argument.
Thanks to Michelin for their support of this work.
All tests passing.
-
Fixed an S3 asset bundle generation bug that caused
.lessfiles to be imported with the wrong file extension if thepublicfolder did not yet exist at the time--create-bundlewas used. Thanks to Michelin for their support of this work. -
Also added an
apostrophe-caches:cleartask to aid in testing various functionality. You must specify the cache name since caches may or may not even be known to Apostrophe at task startup time based on whether and when code calls.getfor each cache name.
All tests passing.
-
The new
testModule: trueoption causes Apostrophe to supply much of the boilerplate for a published npm apostrophe module that wants to test itself as part of an apostrophe instance, i.e. apostrophe-workflow, apostrophe-caches-redis, etc. See those modules for examples of usage. This is a feature for those writing their own npm modules that wish to unit test by initializing Apostrophe and loading the module in question. -
Fixed caching bugs, notably the oembed cache, which is now operating properly. Oembed responses, such as YouTube iframe markup, are now cached for an hour as originally intended which improves frontend loading time.
-
Page type changes only refreshed the schema fields on the first change — now they do it properly after every change.
-
Page type changes use the "busy" mechanism while refreshing the schema fields to prevent user interface race conditions and avoid user confusion.
-
trashis never offered as a schema field of theglobaldoc (mainly a concern withapostrophe-workflow).
All tests passing.
It is now easier to set up Redis or another alternative session store:
'apostrophe-express': {
session: {
secret: 'your-secret-here',
store: {
name: 'connect-redis',
options: {
// redis-specific options here
}
}
}
}
For bc, you can still pass a live instance of a store as the store option, but this way is easier; all you have to do is npm install --save your connect-compatible session store of choice and configure it.
Thanks to Michelin for their support of this work.
All tests passing.
- Overrideable widgetControlGroups method takes (req, widget, options) allowing for better control when customizing these buttons.
- The
createControlsoption of theapostrophe-pagesmodule is now respewcted properly.
All tests passing.
- Fixed a short-lived issue with the reorganize feature.
All tests passing.
This is a significant update containing various accommodations required by the shortly forthcoming Apostrophe 2.x version of the apostrophe-workflow module, as well as other recent enhancements in our queue.
-
Editing an area "in context" on the page when it is part of a widget or piece will always work, even if
contextual: truewas not set. That property is optional and prevents the area from also appearing in the dialog box for editing the content type. -
Multiple select filters are now available for the "manage" view of any piece type. Just like configuring single-select filters, except that you'll add
multiple: trueto the relevant object in youraddFiltersconfiguration for the module. Thanks to Michelin for their support of this work. -
When editing a previous selection of pieces for a join or widget, you can also easily edit them without locating them again in the manage view.
-
"Next" and "previous" links can now be easily added to your
show.htmlpages for pieces. Just set thenextandpreviousoptions for yourapostrophe-pieces-pagessubclass totrue, or to an object with aprojectionproperty for best performance. This will populatedata.previousanddata.nextin yourshow.htmltemplate. For blogs they may seem backwards; they refer to relative position on the index page, and blogs are reverse-chronological. Just switch the terms on the front end in your template in cases where they appear confusing. -
There is now a "pages" option on the admin bar, for cases where "reorganize" is not visible because "Page Settings" is not accessible to the user for the current page.
-
If the
trashInSchemaoption is set totruewhen configuringapostrophe-docs, pages that are in the trash retain their position in the page tree rather than moving to a separate "trash" subtree. In the "reorganize" interface, they are grouped into trash cans displayed beneath each parent page, rather than a single global trash can. This is necessary for the new workflow module and also helpful in any situation where trying to find pages in the trash is more troublesome than explaining this alternative approach.
When trashInSchema is true, users can also change the trash status of a piece or page via "Page Settings" or the "Edit" dialog box of the piece, and it is possible to access "Page Settings" for any page via "Reorganize."
-
The buttons displayed for each widget in an Apostrophe area can be adjusted via the
addWidgetControlGroupsoption of theapostrophe-areasmodule, which can be used to introduce additional buttons. -
Empty
beforeMoveandafterMovemethods have been added to theapostrophe-pagesmodule for the convenience of modules usingimproveto enhance it. -
The
apostrophe-doc-type-managermodule now hasgetEditPermissionNameandgetAdminPermissionNamemethods. These can be overridden by subclasses. For instance, all page subtypes returnedit-apostrophe-pagefor the former because page types can be changed. -
apos.destroy(function() { ... })may be called to shut down a running Apostrophe instance. This does not delete any data. It simply releases the database connection, HTTP server port, etc. This mechanism is extensible by implementing anapostropheDestroymethod in your own module. -
beforeoption forexpressMiddleware. As before any module can provide middleware via anexpressMiddlewareproperty which may be a function or array of functions. In addition, if that property is an object, it may also have abeforesubproperty specifying a module whose middleware should run after it. In this case the actual middleware function or functions must be in amiddlewaresubproperty. -
apos.instancesOf(name)returns an array of modules that extendnameor a subclass of it.apos.instanceOf(object, name)returns true if the givenobjectis a moog instance ofnameor a subclass of it. -
apos.permissions.criteriacan now supply MongoDB criteria restricted to the types the user can edit when a general permission name likeeditoredit-docis asked for. This was never a security bug because permissions for actual editing were checked when individual edits occurred. The change makes it easier to display lists of editable content of mixed types. -
Extending the indexes of Apostrophe's
aposDocscollection is easier to achieve in modules that useimproveto extendapostrophe-docs. -
Removed tests for obsolete, unsupported Node.js 0.10.x. Node.js 4.x is now the minimum version. We do not intend to break ES5 compliance in 2.x, however testing old versions of Node that are not maintained with security patches in any freely available repository is not practical.
-
insertmethod forapos.attachments, mirroring the other modules better. Thanks to Arthur Agombart.
All tests passing.
- Notifications are available, replacing the use of
alert. This feature is primarily for Apostrophe's own administrative features; you can use it when extending the editing UI. Callapos.notify('message')to display a simple message. You can specify severaltypeoptions such aserrorandinfo, and you can also use%swildcards. Everything is localized on the server side. See the documentation for more information. Thanks to Michelin for their support of this work. - The
apostrophe-imageswidget now provides a focal point editor. See the new responsive images HOWTO. Thanks to Michelin for their support of this work. - UX: clicking "edit" on an image you have already selected no longer deselects the image. Thanks to Michelin for their support of this work.
- Bug fix: corrected issue that sometimes prevented joins with pages from editing properly.
- Bug fix: added sort index on
levelandrank, preventing MongoDB errors on very large page trees. - UX: a complete URL is suggested at startup when testing locally. Thanks to Alex Gleason.
All tests passing.
- Fixed recently introduced bug preventing page type switching.
All tests passing.
- Lazy schema field configuration, in general and especially for joins. No more need to specify
idField,idsField,relationshipsFieldor evenlabelfor your schema fields.withTypecan be inferred too in many cases, depending on the name of the join field. You can still specify all of the details by hand.
Also, for reverse joins, there is a new reverseOf option, allowing you to just specify the name of the join you are reversing. This is much easier to understand than specifying the idField of the other join. However that is still permitted.
Lazy configuration is in place for doc types (like pages and pieces) and widget types. It can be extended to other uses of schemas by calling the new validation methods.
-
ckeditor 4.6.2. Resolves #896: you can now create links properly in Microsoft Edge. Our policy is now to check in periodically with new ckeditor releases and just make sure they are compatible with our editor skin before releasing them.
-
apos.areas.fromRichTextcan be used to create an area with a single rich text widget from a trusted string of HTML. Not intended for mixed media, just rich text. Related: bothfromRichTextandfromPlaintextnow correctly give their widgets an_idproperty.
All tests passing.
- Fixed short-lived bug introduced in 2.26.0 re: detecting missing widget types.
All tests passing.
-
Do not crash on missing widget types, print good warning messages.
-
Complete implementation of the explicitOrder cursor filter, replacing a nonfunctional implementation.
-
If the mongodb connection is lost, the default behavior is now to retry it forever, so when MongoDB does get restarted Apostrophe will find it. In addition, a
connectobject may be passed to theapostrophe-dbmodule to be passed on to the MongoDB connect call. -
Spaces added between DOM attributes for better HTML5 compliance.
-
requiredsubfields are now enforced when editing fields of typearray.
Thanks to Michelin for their support of much of the work in this release.
All tests passing.
-
There is now a
readOnlyoption for the standard schema field types. Thanks to Michelin for contributing this feature. -
Apostrophe now displays useful warnings and, in some cases, errors at startup when schemas are improperly configured. This is particularly useful if you have found it frustrating to configure joins correctly. We are continuing to deepen the coverage here.
-
In the manage view, the "published" and "trash" filters now always offer both "yes" and "no," regardless of whether anything is available in those categories. This is necessary because these are the respective defaults, and these are also unusual cases in which it is actually interesting to know nothing is available.
All tests passing.
There is now an object schema field type. It works much like the array schema field type, however there is just one object, represented as an object property of the doc in the database. Thanks to Michelin's development team for contributing this feature.
All tests passing.
The options object of enhanceDate is now passed on to pikaday. Considered a bug fix since the options object was erroneously ignored.
- 2.23.1
All tests passing.
cleanCss needs to know that the output CSS files are going to live in apos-minified in order to correctly parse @import statements that pull in plain .css files. Also, the mechanism for prefixing URLs in CSS code was not applied at the correct stage of the bundling process (the minify stage), which broke the ability to reference fonts, images, etc. via URLs beginning with /modules when using an S3 asset bundle.
All tests passing.
- The "manage" view of
apostrophe-piecesnow supports robust filters, in the same way they were already supported on the front end forapostrophe-pieces-pages. Use theaddFiltersoption to configure them. There is bc with existing filters that relied on the old assumption that manage filters have a boolean API. However now you can specify any field with a cursor filter, which includes most schema fields, notably including joins.
Note that since all of the options are presented in a dropdown, not all fields are good candidates for this feature.
The "manage" view filters now refresh to reflect only the options that still make sense based on the other filters you have selected, reducing user frustration.
See reusable content with pieces for more information and examples.
Thanks to Michelin for their support of this work.
-
apos.utils.isFalseallows you to check for values that are strictly=== falsein templates. -
apos.utils.startCaseconverts property names to English, roughly speaking. It is used as a fallback if a filter does not have alabelproperty. This is primarily for bc, you should add alabelproperty to your fields. -
Production now matches the dev environment with regard to relative URLs in LESS files, such as those used to specify background images or font files. Previously the behavior was different in dev and production, which is a bug.
-
You can now pass a
lessoption toapostrophe-assets, which is merged with the options given toless.renderboth in dev and production. You can use this, for instance, to enablestrictMath. -
apostrophe.oembed'sfetchmethod now propagates itsoptionsobject tooembettercorrectly. Thanks to Fotis Paraskevopoulos.
All tests passing.
- Apostrophe now supports publishing CSS and JS assets via S3 rather than serving them directly.
Apostrophe already had an option to build asset "bundles" and deploy them at startup, as described in our cloud HOWTO. However this serves the assets from the cloud webserver, such as a Heroku dyno or EC2 instance. It is now possible to serve the assets from Amazon S3.
See the updated cloud HOWTO for details.
Thanks to Michelin for their support of this work.
-
Enforce string field
minandmaxproperties on server side. -
When validation of a form with tabs fails, such as a pieces edit modal, activate the correct tab and scroll to the first error in that tab.
-
thanks to Ludovic Bret for fixing a bug in the admin bar markup.
All tests passing.
- For a small performance boost,
deferoption can be set totruewhen configuring any widget module. This defers calls to theloadmethod until just before the page is rendered, allowing a single query to fetch them all in simple cases. This is best applied to theapostrophe-images-widgetsmodule and similar widgets. It should not be applied if you wish to access the results of the join in asynchronous code, because they are not available until the last possible moment.
Thanks to Michelin for their support of this work.
-
You can also set
deferImageLoadingtotruefor theapostrophe-globalsmodule if you want the same technique to be applied when loading theglobaldoc's widgets. This does not always yield a performance improvement. -
Bug fix: if two crops of the same image were present in separate widgets on a page, only one of the crops would be seen in template code. This issue has been resolved.
All tests passing.
- The search filter is once again available when choosing images. This involved a deeper fix to modals: filters for sliding modals were not being properly captured and hoisted into the shared part of the outer div. This is now being done exactly as it is done for the controls (buttons) and the instructions.
To avoid incompatibility with existing uses of self.$filters, such as in the manage modal, they are captured to self.$modalFilters. A small change to the manage modal was needed to take advantage of this.
- Moved a warning message from
console.logtoconsole.error.stdoutshould never be used for warnings and errors. Moving toward clean output so that command line tasks can be safely used in pipelines.
All tests passing.
Improved UI for editing widgets. The edit button is no longer separate from the area-related controls such as up, down, etc. This reduces clutter and reduces difficulty in accessing widgets while editing.
All tests passing.
When autocompleting doc titles to add them to a join, Apostrophe again utilizes search result quality to display the best results first.
All tests passing.
This is a significant update with two useful new features and various minor improvements.
- Support for batch uploads. The
apostrophe-imagesandapostrophe-filesmodules now implement batch uploads by default.
When you click "New File" or "New Image," you now go directly to the file browser, and if you select multiple files they are uploaded without a modal dialog appearing for each one; the title and slug are populated from the filename, and that's that.
You can also drag one or more files directly to the chooser/manager modal.
If you are choosing files or images for a widget, they are automatically selected after a batch upload.
This feature can be disabled by setting the insertViaUpload option to false for apostrophe-images or apostrophe-files. If you are adding required fields to apostrophe-images or apostrophe-files, then batch uploading is not the best option for you because it would bypass that.
If you wish, you can enable the feature for your own apostrophe-pieces modules that have an attachment field in their schema by setting the insertViaUpload option to true. However please note that this does not currently do anything for pieces that refer to an image or file indirectly via widget.
- Global preference editing, and a standard UI to roll back to earlier versions of global content. There is now a "Global Content" admin bar button. By default, this launches the version rollback dialog box for shared global content.
However, if you use addFields to add schema fields to the apostrophe-global module, this button instead launches an editing modal where you can edit those fields, and also offers a "Versions" button accessible from there.
Global preferences set in this way are accessible in all situations where data.global is available. This is very useful for creating project-wide preference settings.
All the usual features of schemas can be used, including groupFields. Of course, if you choose to use joins or widgets in global content, you should keep the performance impact in mind.
-
Various UX fixes to the manager and chooser modals.
-
If there is a
minSizesetting in play, that information is displayed to the user when choosing images. -
The
checkboxesschema field type now supports thebrowseFiltersfeature. -
When batch file uploads fail, a more useful set of error messages are displayed.
All tests passing.
- When saving any doc with a schema, if an attachment field does not match a valid attachment that has actually been uploaded, that field is correctly nulled out. In addition, if the attachment's file extension is not in a valid fileGroup as configured via the attachments module, the field is nulled out. Finally, the
crop: trueoption for attachments is saved successfully. This option allows for attachments to have a crop that is inherent to them, useful when there is no widget standing between the doc and the attachment.
All of these changes correct bugs in intended behavior. Certain checks were present in the code but not completely functional. If you need to update your configuration to add file extensions, apostrophe-attachments.
All tests passing.
- As always, Apostrophe always populates
req.data.home; whenreq.data.page._ancestors[0]exists that is used, otherwise Apostrophe carries out a separate query. However as a performance enhancement, you may now disable this additional query by passing thehome: falseoption to theapostrophe-pagesmodule. Note thatreq.data.homeis not guaranteed to exist if you do this.
As for children of the home page, for performance you may now pass home: { children: false } option to the apostrophe-pages module. This option only comes into play when using filters: { ancestors: false }.
Thanks to Michelin for their support of this work.
All tests passing.
-
Performance enhancement: when fetching
req.data.homedirectly in the absence ofreq.data.page._ancestors[0], such as on the home page itself or a non-page route like/login, we must apply the same default filters before applying the filter options, namely.areas(false).joins(false), otherwise duplicate queries are made. -
Fixed bug in as-yet-unused
schemas.exportmethod caught by babel's linter.
Thanks to Michelin for their support of this work.
All tests passing.
- New batch editing features for pieces! You can now use the checkboxes to select many items and then carry out the following operations in one step: trash, rescue from trash, publish, unpublish, tag and untag.
In addition there is a clearly documented procedure for creating new batch editing features with a minimum of new code.
-
Several bugs in the array editor were fixed. Up, down and remove buttons work properly again, an aesthetic glitch was resolved and redundant ordinal numbers do not creep in when managing the order of an array without the
titleFieldoption. -
Logging out completely destroys the session. While the standard behavior of
req.logoutin the Passport module is only to break the relationship between theuserobject and the session, users expect a clean break.
All tests passing.
- Members of a group that has the admin permission for a specific piece type can now move pieces of that type to and from the trash. (This was always intended, so this is a bug fix.)
- For better out-of-the-box SEO, an
altattribute with the title of the image is now part of theimgmarkup ofapostrophe-imageswidgets.
All tests passing.
-
Fixed XSS (cross-site scripting) vulnerability in
req.browserCallandapos.push.browserCall. -
Removed confusing strikethrough of "Apply to Subpages" subform when the permission is being removed rather than added.
-
Improved UX of area widget controls.
-
Improved modal array tab UI and CSS.
-
The
oembedReadyApostrophe event is now emitted correctly afterapostrophe-oembedrenders an oembed-based player, such as a YouTube video player for theapostrophe-videowidget. This event can be listened for viaapos.on('apostrophe-oembed', fn)and receives a jQuery object referring to the relevant element.
All tests passing.
-
arrayschema fields now accept alimitoption. They also support thedefproperty to set defaults for individual fields. The array editor code has been refactored for better reliability and performance and documentation for the methods has been written. -
Relative
@importstatements now work when you push plain.cssfiles as Apostrophe assets. There is no change in behavior for LESS files. Thanks to Fredrik Ekelund. -
Controls such as the "Finished" button of the reorganize modal were floating off the screen. This has been fixed.
All tests passing.
-
If you have tried using
piecesFilterswith atagsfield type, you may have noticed that when the query string parameter is present but empty, you get no results. This is suboptimal because that's a common result if you use an HTML form to drive the query. An empty string for atagsfilter now correctly does nothing. -
In
apostrophe-rich-text-widgets, initialize CKEditor oninstanceReady, rather than via a dodgy timeout. Thanks to Frederik Ekelund for finding a better way!
All tests passing.
-
Reintroduced the reorganize feature for editors who have permissions for some pages but not others. You are able to see the pages you can edit and also their ancestors, in order to navigate the tree. However you are able to drag pages only to parents you can edit.
-
Introduced the new
deleteFromTrashoption to theapostrophe-pagesmodule. If this option is enabled, a new icon appears in "reorganize" when looking at pages in the trash. This icon allows you to permanently delete a page and its descendants from the site.
The use of this option can lead to unhappy customers if they do not clearly understand it is a permanent action. For that reason, it is disabled by default. However it can be quite useful when transitioning from the initial site build to long-term support. We recommend enabling it during that period and disabling it again after cleanup.
-
"Reorganize" no longer displays nonfunctional "view" and "trash" icons for the trash and pages inside it.
-
The tests for the
apostrophe-locksmodule are now deterministic and should always pass.
All tests passing.
Fixed a bug which could cause a crash if the sort filter was explicitly set to search and no search was actually present. Conditions existed in which this could happen with the autocomplete route.
Due to a miscommunication the version number 2.15.0 had been previously used. The description below was originally intended for 2.15.0 and has been published as 2.15.1 purely to address the version numbering conflict.
All tests passing.
apos.permissions.addPublicaccepts multiple arguments and array arguments, adding all of the permission names given including any listed in the arrays.- Permissions checks for pieces admin routes longer check for req.user, checking for the appropriate
edit-permission is sufficient and makes addPublic more useful. - Updated the
i18nmodule to address a problem where labels that happened to be numbers rather than strings would crash the template if passed to__(). - Documentation improvements.
All tests passing.
The mechanism that preserves text fields when performing AJAX refreshes was preserving
other types of input elements. Checkboxes, radio buttons and type="submit" are now
properly excluded from this mechanism.
Fixed #385: if a page is moved to the trash, its slug must always change, even if it has been edited so that it no longer has its parent's slug as a prefix. In addition, if the resulting slug of a descendant of the page moving to the trash conflicts with an existing page in the trash, steps are taken to ensure uniqueness.
All tests passing.
-
The
apos.utils.clonePermanentmethod no longer turns objects into long arrays of nulls if they happen to have alengthproperty.lodashuses thelengthproperty as an indicator that the object should be treated as an array, but this would be an unrealistic restriction on Apostrophe schema field names. Instead,clonePermanentnow usesArray.isArrayto distinguish true arrays. This fixes a nasty bug when importing content from A1.5 and subsequently editing it. -
When a user is logged in there is an
apos.userobject on the browser side. Due to a bug this was an empty object. It now containstitle,_idandusernameproperties as intended.
All tests passing.
- A version rollback dialog box for the
globaldoc is now opened if an element with thedata-apos-versions-globalattribute is clicked. There is currently no such element in the standard UI but you may introduce one in your own layout if you have mission-critical content in theglobaldoc that is awkward to recreate after an accidental deletion, such as a custom sitewide nav. - An error message is correctly displayed when login fails.
- Many UI messages are now passed through the
__()internationalization helper correctly. Thanks totimaebi.
All tests passing.
The data-apos-ajax-context feature had a bug which prevented ordinary anchor links from performing AJAX refreshes correctly.
All tests passing.
The apostrophe-attachments module now calls apos.ui.busy correctly on the fieldset so that the busy and completed indicators are correctly shown and hidden. Previously the string 0 was passed, which is not falsy.
All tests passing.
- Developers are no longer required to set
instantiate: falseinapp.jswhen configuring an npm module that uses theimproveproperty to implicitly subclass and enhance a different module. In addition, bugs were fixed in the underlyingmoog-requiremodule to ensure that assets can be loaded from thepublicandviewsfolders of modules that useimprove. stringhas replacedcsvas the property name of the schema field converters that handle plaintext. Backwards compatibility has been implemented so that existingcsvconverters will work transparently and calls toconvertwithcsvas thefromargument still work as well. In all new custom field types you should saystringrather thancsv. There is no change in the functionality or implementation other than the name.
All tests passing.
You can now add middleware to your Apostrophe site via any module in your project. Just add an self.expressMiddleware method to your module, which takes the usual req, res, next arguments. Or, if it's more convenient, set self.expressMiddleware to an array of such functions. "Module middleware" is added immediately after the minimum required Apostrophe middleware (bodyParser, req.data, etc), and before any routes.
All tests passing.
Fixed bug in autoPreserveText feature of our data-apos-ajax-context mechanism; also, restricted it to text inputs and textareas that actually have the focus so that you can replace their values normally at other times
All tests passing.
A very minor fix, but 2.10.1 had a very noisy console.log statement left in.
All tests passing.
- The built-in cursor filters for
floatandintegerno longer incorrectly default to filtering for docs with the value0if the value being filtered for is undefined or null. They default to not filtering at all, which is correct.
All tests passing.
- Apostrophe now automatically recompiles modified Nunjucks templates. This means you can hit refresh in your browser after hitting save in your editor when working on
.htmlfiles. Also note that this has always worked for.lessfiles. - Fixed a longstanding bug in
joinByArrayReverse, which now works properly.
All tests passing.
- Starting with MongoDB 3.3.x (?), it is an error to pass
safe: truewhen callingensureIndex, and it has never done anything in any version. In our defense, cargo-cult practice was probably adopted back in the days when MongoDB would invoke your write callback without actually confirming anything unless you passedsafe: true, but apparently this was never a thing for indexes. Removed all thesafe: truearguments fromensureIndexcalls. - Added a
beforeAjaxApostrophe event to facilitate progress display and animations when using the newdata-apos-ajax-contentfeature.
All tests passing.
- Fixed an omission that prevented the use of the back button to undo the very first click when using the new
data-apos-ajax-context. Later clicks worked just fine, but for the first one to work we need a call toreplaceStateto make it possible to restore the original query.
All tests passing.
- Two major new features in this release: built-in filters for most schema fields, and built-in AJAX support for
apostrophe-pieces-pages. These combine to eliminate the need for custom code in a wide array of situations where you wish to allow users to browse and filter blog posts, events, etc. In most cases there is no longer any need to write your owncursor.jsor your own AJAX implementation. The provided AJAX implementation handles browser history operations, bookmarking and sharing properly and is SEO-friendly.
See the official summary of the pull request for details and examples of usage.
- We also fixed a bug in the
refinalizefeature of cursors. state.criteria is now cloned before finalize and restored after it. Otherwise many criteria are added twice after refinalize which causes a fatal error with a few, like text search in mongodb.
In addition, we merged a contribution from Fotis Paraskevopoulos that allows a bodyParser option with json and urlencoded properties to be passed to the apostrophe-express module. Those properties are passed on to configure those two body parser middleware functions.
All tests passing.
APOS_MONGODB_URIenvironment variable is used to connect to MongoDB if present. Helpful for cloud hosting. See the new deploying Apostrophe in the cloud HOWTO.APOS_S3_BUCKET,APOS_S3_ENDPOINT(optional),APOS_S3_SECRET,APOS_S3_KEY, andAPOS_S3_REGIONenvironment variables can be used to configure Apostrophe to use S3 for uploaded media storage. This behavior kicks in ifAPOS_S3_BUCKETis set. See the new deploying Apostrophe in the cloud HOWTO.- New advisory locking API accessible via
apos.locks.lockandapos.locks.unlock.apostrophe-migrations:migrateis now wrapped in a lock. More locks are coming, although Apostrophe was carefully designed for benign worst case outcomes during race conditions. - Better asset deployment for Heroku and other cloud services.
node app apostrophe:generation --create-bundle=NAMEnow creates a new folder,NAME, containing assets that would otherwise have been written topublic. Launching a server with theAPOS_BUNDLEenvironment variable set toNAMEwill then copy that bundle's contents intopublicbefore listening for connections. See the new deploying Apostrophe in the cloud HOWTO. apostrophe-pieces-pagesindex pages are about 2x faster; discovered we were inefficiently deep-cloningreqwhen cloning a cursor.- Helpful error message if you forget to set the
nameproperty of one of yourtypeswhen configuringapostrophe-pages.
- We do a better job of defaulting to a sort by search match quality if full-text search is present in a query. Under the hood this is powered by the new
defaultSortfilter, which just stores a default value for thesortfilter to be used only ifsearch(and anything else with an implicit preferred sort order) is not present. No more lame search results for blog posts. You can explicitly set thesort()filter in a cursor override if you really want to, but trust us, whensearchis present sorting by anything but search quality produces poor results. - Fixed bugs in the sanitizer for page slugs. It is now impossible to save a slug with trailing or consecutive slashes (except the home page slug which is allowed to consist of a single "trailing" slash). Added unit tests.
- Apostrophe's dropdown menus, etc. will more robustly maintain their font size in the presence of project-level CSS. There is an explicit default font size for
.apos-ui.
All tests passing.
- The auto-suggestion of titles upon uploading files also suggests slugs.
- The auto-suggestion of titles and slugs applies to both "files" and "images."
- Reduce the clutter in the versions collection by checking for meaningful change on the server side, where final sanitization of HTML, etc. has taken place to iron out distinctions without a difference.
- Use the permission name
edit-attachmentconsistently, so that callingaddPublic('edit-attachment')has the intended effect. - Manage view of pieces does not crash if
updatedAtis missing from a piece.
All tests passing.
- Choosers and schema arrays play nicely with the new fixed-position tabs.
- Better CSS solution to positioning the attachment upload buttons which doesn't interfere with other styles.
- Images in the chooser choices column "stay in their lane."
- Better error message when an attempt to edit an area with a hyphenated name is used.
- Array edit button fixed.
- The
type()cursor filter now has a finalizer and merges its criteria there at the very end, so that you can override a previous call to it at any time prior to invokingtoArrayor similar. - Area controls no longer interfere with visibility of widget type selection menu.
All tests passing.
relationshipfields defined forjoinByArraycan now have aninline: trueflag. If they are inline, they are presented right in the chooser, rather than appearing in a separate modal dialog reachable by clicking an icon. This feature should be used sparingly, but that's true of relationship fields in general.- Permissions editing for pages now takes advantage of the new inline relationship fields to make the "apply to subpages" functionality easier to discover.
- When uploading files or images, the title field is automatically suggested based on the filename.
- Improvements in form field UX and design.
- When choosing pieces (including images), if you elect to create a new piece it is automatically added to the selection.
- When choosing pieces, if the
limitis reached and it is greater than 1, a helpful message appears, and the UI changes to make clear that you cannot add items until you remove one. If the limit is exactly 1, a new selection automatically replaces the current selection, and singular language is used to clarify what is happening. - Syntax errors in "related types" such as cursors now produce an improved error message with filename and line number.
- Showstopper errors during startup are reported in a less redundant way.
All tests passing.
- New
blockLevelControls: trueoption to areas ensures controls for "blocks," i.e. "layout" widgets whose primary purpose is to contain other widgets, can be easily distinguished from controls for "regular" areas nested inside them. Think of a "two-column" or "three-column" widget with three areas in its template. The controls for these areas are displayed in a distinct color and various visual affordances are made to ensure they are accessible when things would otherwise be tightly spaces. - General improvements to the usability of area-related controls.
- The search index now correctly includes the text of string and select schema fields found in widgets, pieces, pages, etc., as it always did before in 0.5. You may use
searchable: falseto disable this on a per-field basis. - Search indexing has been refactored for clarity (no changes to working APIs).
- Checkboxes for the
checkboxesschema field type are now styled. - "View file" links in the file library are now styled as buttons.
All tests passing.
- The
minSizeoption toapostrophe-imageswidgets now works properly when cropping. - The cropper no longer starts out cropping to the entire image, as this made it unclear what was happening. However if you click the crop button and then just save you still get reasonable behavior.
- Bigger crop handles.
- Textarea focus state receives the same "glow" as a regular text input field.
- Small documentation updates.
All tests passing.
- Implemented
apos.areas.fromPlaintext, which accepts a string of plaintext (not markup) and returns an area with a singleapostrophe-rich-textwidget in it, containing that text. Useful in implementing importers. - The so-called
csvimport mode ofapos.schemas.convertworks properly for areas, using the above. Although it is called csv this mode is really suitable for any situation in which you have plaintext representations of each property in an object and would like those sanitized and converted to populate a doc. - Bug fix: emit the
enhanceApostrophe event only once on page load. This event is emitted only when there is new content that has been added to the page, e.g. once at page load, and also when a new widget is added or updated, etc. The first argument to your event handler will be a jQuery element which will contain only new elements. - Legacy support for
data/portanddata/addressfiles has been restored. (Note thatPORTandADDRESSenvironment variables supersede these. In modern Stagecoach deploymentsdata/portis often a space-separated list of ports, and thedeployment/startscript parses these out and launches multiple processes with different PORT variables.)
All tests passing.
Workarounds for two limitations in MongoDB that impact the use of Apostrophe cursors:
- The
addLateCriteriacursor filter has been introduced. This filter should be used only when you need to invoke$nearor another MongoDB operator that cannot be used within$and. The object you pass toaddLateCriteriais merged with the criteria object that is built normally by the cursor. Use of this filter is strongly discouraged unless you must use operators that do not support$and. - Custom filters that invoke
$nearor other MongoDB operators that are incompatible with$textqueries may callself.set('regexSearch', true)to force the cursor to use a regular expression search rather than full MongoDB full-text search, if and when thesearch()filter is called on the same cursor. This was implemented to allow combination of full-text and geographical searches, subject of course to the limitation that regular expression search is not indexed. It also doesn't sort by quality, but$nearprovides its own sort by distance.
Since these are new features a minor version level bump is appropriate. However neither of these is a feature that a typical site developer will need to call directly.
All tests passing.
- The quality of the autocomplete search results shown when selecting pages or pieces via a join was low. This has been corrected by calling the
.sort('search')filter to sort by search result quality rather than the default sort order for the doc type manager in question. - All of the autocomplete suggestions fit on the screen on reasonably sized displays. With the recent addition of the "flip" feature to push the suggestions up rather than down if the bottom of the screen would otherwise be reached, this is critical to show the first and best suggestion. Further discussion for future UX improvement in issue 704.
All tests passing.
- Fixed a bug in the new "copy page" feature that affects pages that have
nullproperties. - Improved the experience of using the widget controls to manage the widgets in an area.
- The
loginmodule now has an alias,apos.login, like other core modules. - Updated the jquery projector plugin to the latest version.
All tests passing.
- Fixed a bug affecting the use of
arrangeFieldsin modules that extend another module's use ofarrangeFields. Added unit test based directly on a real-world project. baseUrlproject-wide option added, yielding the same benefit as in 0.5: you get absolute URLs for all pages everywhere. (If you don't want absolute URLs, just don't set it.) This is very beneficial when generatingog:metatags for Facebook, or generating emails.- A direct link to the original file has been added to the file manager's editor modal.
All tests passing.
- Addition of slugs to projection for autocomplete is now done in a way that still allows overrides at the doc level to add other properties.
- Addition of slugs to projection for autocomplete works for joins with a specific page type, too.
- Fixed a chicken-and-egg problem in the global module that kicked in if the "global" doc contains widgets powered by modules not yet initialized at the time the global module checks for the existence of the doc.
All tests passing.
Fixed an oversight: the new pageBeforeCopy global method now takes req as its first parameter. Since 2.2.0 was first published 5 minutes ago and this method has not yet been documented this is not regarded as a bc break.
All tests passing.
- Fixed bug that broke removal of permissions for pages.
- "Copy Page" feature added to the page menu.
- Automatically reposition the autocomplete dropdown for joins if it would collide with the bottom of the window.
- Include page slugs in the autocomplete dropdown for joins with pages.
chooserChoiceBase.htmlrestored; some projects were depending on extending it, which is a useful technique.
All tests passing.
- Admin bar: previously grouped fields can be re-grouped successfully, so concatenating admin bar configuration works just as well as concatenating
addFieldsarrays - Files widget displays upload button in the same user-friendly position as the images widget
- Font size for tabs and help labels is explicit to avoid side effects from project-level CSS
All tests passing.
- Previously chosen items that now reside in the trash no longer break the chooser for editing joins
- All joins editable; certain edge cases weren't getting blessed
- A field appears properly when two diferent choices list it for
showFields - As in 0.5, a required field hidden by
showFieldsis not required (but will be if you elect the choice that shows it)
All tests passing.
- A typo in the unit tests caused unit tests to fail. This has been fixed.
- The recent addition of the HTML5 doctype caused the login page to be invisible in the sandbox project (not the boilerplate project). This has been fixed.
- The recent addition of the HTML5 doctype caused the admin bar to appear with a slight visual defect. This has been fixed.
Fix for #668, crash occurring when admin bar group leader starts out too close to the end of the admin bar items array.
Full Windows compatibility restored. The "recursively copy asset folders if on Windows" behavior from 0.5 was reimplemented. This is necessary to allow Apostrophe to run as a non-administrator on Windows. Running as administrator is the moral equivalent of running as root on Linux, which we would never recommend.
Since Apostrophe did not function previously on Windows and there is no behavior change on Mac/Linux this is effectively a bug fix rather than a new feature, thus 2.1.1.
-
Introduced the new
apos.areas.richTextandapos.areas.plaintextmethods, which are also available in templates by the same names. -
Added and documented the
addImageSizesoption of theapostrophe-attachmentsmodule.
- The
apostrophe-loginmodule now invokesloginAfterLogin(req, callback)on all modules that have such a method, viaapos.callAll. Modules that do not need a callback can supply this method with only one argument. Afterwards,apostrophe-loginredirects toreq.redirect, as is supported elsewhere in Apostrophe. So you can assign toreq.redirectin your callback to change the user's destination after a successful login. Ifreq.redirectis not set, the user is redirected to the home page.
The ancestors and children filters defaulted to areas(false), but joins(false) was omitted, contrary to documentation which has always indicated the information returned is limited for performance. This was fixed. You can still override freely with the filters option to apostrophe-pages.
The HTML5 doctype was added to outerLayoutBase. HTML5 was always assumed, and the absence of the doctype broke jQuery's support for distinguishing $(window).height() from $(document).height(), causing runaway infinite scroll loading.
Warning message instructions for configuring the session secret were fixed (the actual location has not changed).
Previously the contextual flag of a pieces module was not considered before deciding to redirect to the "show page" for the piece, which might not exist. This has been fixed. It should only happen when the module has contextual: true, creating a reasonable expectation that such a page must exist.
Packaging and documentation issues only.
Inaugural npm release of Apostrophe 2.x, which was used prior to that in many projects via git dependencies.