= !TracDev/ApiChanges/0.12 = [[PageOutline(2-4,Summary,inline)]] == New Dependencies == === Babel (optional) === The internationalization support (i18) for Trac is depending on [http://babel.edgewall.org/ Babel]. It's perfectly fine to go on using Trac without it, but then of course the interface will remain in English. == Modifications made to the 0.11 API == === Modified Interfaces === ==== `IWikiMacroProvider` ^[source:trunk/trac/wiki/api.py@8372:85#L72 (0.12)] [source:branches/0.11-stable/trac/wiki/api.py@8372:90#L77 (0.11)]^ ==== #IWikiMacroProvider Added an optional argument `args` to `IWikiMacroProvider.expand_macro()` to contain the shebang-line arguments when using wiki processor syntax. For example, with the following content: {{{ {{{ #!MyMacro test=123 other="This is a text" This is the content. }}} }}} The macro `MyMacro` will have its `expand_macro()` called with `args={'test': '123', 'other': 'This is a text'}`. See also #8204. ==== `IWikiPageManipulator` ^[source:trunk/trac/wiki/api.py@8429:64#L52 (0.12)] [source:branches/0.11-stable/trac/wiki/api.py@8429:69#L57 (0.11)]^ ==== #IWikiPageManipulator This interface has not actually been changed, but the implementation has been fixed so that it actually does what it promises, that is, ''validate a wiki page '''after it's been populated''' from user input''. Previously, `page.text` would contain the old text, and the new text would typically be retrieved with `req.args.get('text')` as a workaround. The `page` now has the new text in `page.text`, and the old text in `page.old_text`. See also #7731. === Other Changes to the 0.11 API === ==== `prevnext_nav` support for i18n ^[source:trunk/trac/web/chrome.py@8597:158-164#L158 (0.12)] [source:branches/0.11-stable/trac/web/chrome.py@8550:139-144#L139 (0.11)]^ ==== #prevnext_nav The `prevnext_nav` function used for adding contextual navigation links was not i18n friendly. In order to make the need for adaptation obvious, the arity of the function has changed and the label for the previous and next links have to be spelled out in full. ==== `Href` with an empty base ^[source:trunk/trac/web/tests/href.py@8551:61-62,76-78#L57 (0.12)] [source:branches/0.11-stable/trac/web/tests/href.py@8551:63-64,79-81#L57 (0.11)]^ ==== #Href The `Href` class has been changed to ensure that it always generates valid URLs, even with an empty base. In 0.11, the following uses all return an empty string: {{{ #!python # 0.11 >>> href = Href('') # Also applies to Href('/') >>> href() '' >>> href('/') '' }}} In 0.12, the same expressions return a valid relative URL: {{{ #!python # 0.12 >>> href = Href('') >>> href() '/' >>> href('/') '/' }}} This change will break plugins that use the following idiom to concatenate the base URL with a path starting with a slash: {{{ #!python # 0.12 >>> href = Href('') >>> path = '/path/to/page' >>> href() + path # Broken '//path/to/page' }}} For this specific use case, a new syntax has been added to avoid doubled slashes: {{{ #!python # 0.12 and 0.11.6 >>> href = Href('') >>> path = '/path/to/page' >>> href + path # New syntax '/path/to/page' }}} The new syntax has been backported to 0.11-stable in 0.11.6 to facilitate compatibility of plugins with both 0.11.6 and 0.12. If compatibility with older releases of the 0.11.x branch is required, the following code can be used: {{{ #!python # 0.12 and 0.11.x >>> href = Href('') >>> path = '/path/to/page' >>> href().rstrip('/') + path # Compatibility '/path/to/page' }}} See also #8159. ==== [TracStandalone tracd] and HTTP/1.1 ==== Since 0.11.5, tracd could be used with the `--http11` flag, which would select the use of the HTTP/1.1 protocol and most notably activate Keep-Alive connections. This is now the default behavior in 0.12. This has some important consequences for plugins which send content directly to the client. They should take care of setting the `Content-Length` header properly, otherwise the browser will simply "hang". This means that any: {{{ #!python req.write(content) }}} must be preceded by a: {{{ #!python req.send_header('Content-Length', len(content)) }}} Don't forget to do that for ''any'' data directly sent back to the client, including responses for XHRs (e.g. r8300). This requires some discipline in the coding, but the benefit is a huge performance boost for tracd, so it's well worth the price. In order to make errors more immediately visible, the `Request.write` method is more strict in 0.12: it only accepts `str` data parameter, and will also raise an exception if the Content-Length header was not set prior to the call. See #8020 and #8675 for details. ==== `Repository` constructor ^[source:sandbox/multirepos/trac/versioncontrol/api.py@8677:682,688-691#L679 (0.12)] [source:branches/0.11-stable/trac/versioncontrol/api.py@8353:191#L188 (0.11)]^ ==== #Repository ''TODO: Describe removal of `authz` argument (when done)'' ''TODO: Fix (0.12) link after multirepos merge'' A new argument `params` has been added to the `Repository` constructor, which must be propagated from derived classes back to `Repository.__init__()`. `params` is a dictionary containing various parameters for the repository, and is stored as a `.params` attribute in `Repository`. The value for the key `"name"` is the repository name (available as `.reponame`) as displayed in the source browser. The value for the key `"id"` (available as `.id`) is the surrogate key identifying the repository in the database. See #8731 for details. ==== `CachedRepository` constructor ^[source:sandbox/multirepos/trac/versioncontrol/cache.py@8353:45#L40 (0.12)] [source:branches/0.11-stable/trac/versioncontrol/cache.py@8353:45#L38 (0.11)]^ ==== #CachedRepository ''TODO: Fix (0.12) link after multirepos merge'' In 0.11, the first argument to the `CachedRepository` constructor was a callable that would return a DB instance when called. In 0.12, the first argument has been changed to an `Environment` instance. Subclasses of `CachedRepository` must therefore be changed accordingly, and components implementing `IRepositoryConnector` and returning a `CachedRepository` or a subclass must pass `self.env` instead of a `getdb` callable. == New in the 0.12 API == === New Classes === ==== `trac.cache.CacheProxy` ^[source:trunk/trac/cache.py@#L87 (0.12)]^ ==== #CacheProxy There's a new cache subsystem in [source:trunk/trac/cache.py trac.cache] allowing Component instances to cache any data in a safe way. Whenever the cache entry is invalidated, the cached value will be automatically refreshed at the next retrieval, even if the invalidation occurs in a different process. This makes the `config.touch()` trick obsolete. New decorators: - `trac.cache.cached_value` ^[source:trunk/trac/cache.py@#L25 (0.12)]^ - `trac.cache.cached` ^[source:trunk/trac/cache.py@#L65 (0.12)]^ See TracDev/Proposals/CacheInvalidation#CacheManager for details. === New Interfaces === ==== `trac.ticket.api.IMilestoneChangeListener` ^[source:trunk/trac/ticket/api.py@8828:141-157#L140 (0.12)]^ ==== #IMilestoneChangeListener Components implementing the `IMilestoneChangeListener` interface are notified upon creation, modification and deletion of milestones. The milestone model object is passed to each handler. Moreover, on modification an additional dictionary is passed, containing the attributes that were modified and their previous values. See #6543 for details.