Shortcodes have traditionally had a problem that they are inside <p> tags,
but generate block level elements. This breaks HTML compliance.
This makes the shortcode parser now mutate the DOM based on the "class" attribute on
the shortcode to insert the generated block level element at the right place in the DOM
- for "left" and "right" elements it puts them just before the block level
element they are inside
- for "leftAlone" and "center" elements it splits the DOM around the shortcode.
The trade off is that shortcodes are no longer "text level" features. They need
knowledge of the HTML they are in to perform this transformation, so they can
only be used in (valid) HTML
The _ss_environment.php file can now be in any parent folder of the framework (according to realpath())
Removing the description of '3 levels deep' and replaced with explanation of infinite depth.
- Avoid using "if" to check for file existence (use try_files instead)
- Replicate the behavior of the .htaccess files
- TODO: get static error pages to work
Title in CMS is set using header X-Title. But UTF-8 characters can't be used in HTTP headers. So the title should be encoded just before sending X-Title header and decoded before setting HTML document title (fixes#7942).
In 3.0 there was some confusion about whether DataLists and ArrayLists
were mutable or not. If DataLists were immutable, they'd return the result, and your code
would look like
$list = $list->filter(....);
If DataLists were mutable, they'd operate on themselves, returning nothing, and your code
would look like
$list->filter(....);
This makes all DataLists and ArrayList immutable for all _searching_ operations.
Operations on DataList that modify the underlying SQL data store remain mutating.
- These functions no longer mutate the existing object, and if you do not capture the value
returned by them will have no effect:
ArrayList#reverse
ArrayList#sort
ArrayList#filter
ArrayList#exclude
DataList#dataQuery (use DataList#alterDataQuery to modify dataQuery in a safe manner)
DataList#where
DataList#limit
DataList#sort
DataList#addFilter
DataList#applyFilterContext
DataList#innerJoin
DataList#leftJoin
DataList#find
DataList#byIDs
DataList#reverse
- DataList#setDataQueryParam has been added as syntactic sugar around the most common
cause of accessing the dataQuery directly - setting query parameters
- RelationList#setForeignID has been removed. Always use RelationList#forForeignID
when querying, and overload RelationList#foreignIDList when subclassing.
- Relatedly,the protected variable RelationList->foreignID has been removed, as the ID is
now stored on a query parameter. Use RelationList#getForeignID to read it.