[[PageOutline]] = !TracDev/ApiChanges/0.10 = This page is aimed to help plugin developers to port their 0.9 plugin to Trac 0.10. Most of the initial examples are coming from the migration of the [trachacks:DoxygenPlugin] (#TH662). == General Changes == === Use `unicode` strings === The most important single change in 0.10 was the switch to using `unicode` everywhere internally. See TracDev/UnicodeGuidelines. === Using `self.env.href` is deprecated === Generated URLs should most of the time be relative to the URL which was used for the request being processed. So wherever you can, '''use `req.href` instead'''. Usage of `self.env.href` is still possible when no Request object is available. === New Configuration API for Components === Components can still use `self.config.get...`, but there's now a better way to do this, which among other things make it easy to document your configuration settings. When you had: {{{ #!python class DoxygenPlugin(Component): implements(...) # ... def match_request(self, req): # Get config variables. base_path = self.config.get('doxygen', 'path', '/var/lib/trac/doxygen') }}} You should now write: {{{ #!python class DoxygenPlugin(Component): implements(...) base_path = Option('doxygen', 'path', '/var/lib/trac/doxygen', """Directory containing doxygen generated files.""") # ... def match_request(self, req): base_path = self.base_path # actually, use `self.base_path` where you'd used `base_path` }}} Besides the string `Option`, you have also access to more specialized types for you configuration settings, like `BoolOption`, `IntOption`, `ListOption`, etc. (see [source:trunk/trac/config.py@head#L326 config.py]). By using the [WikiMacros#TracIni-macro TracIni(doxygen)] macro, you'll get the documentation for all your settings. === New API for Generating HTML fragments === Since Trac [milestone:0.9.3], the generation of HTML using ClearSilver has been modified so that by default, every string content will get HTML-escaped (e.g. "
" replaced by "<br />"). Most plugin developers discovered this change the hard way ;) The recommended way for avoiding this escaping was to wrap the strings containing markup in a `Markup` instance. While this is still valid in 0.10, you should note that `Markup` is now defined in the `trac.util.html` module, though importing from `trac.util` will still work. More importantly, there's now a new way to programmatically generate markup content, using the `html` object, also defined in that `trac.util.html` module. That object will dynamically generate `Element` objects, that can be nested. The way to use it is: {{{ html.(*other_elements_or_strings, **attributes) }}} Example: (from the [trachacks:DoxygenPlugin]) {{{ #!diff --- a/doxygentrac/doxygentrac.py Tue Aug 29 14:05:15 2006 +0200 +++ b/doxygentrac/doxygentrac.py Wed Aug 30 14:35:12 2006 +0200 @@ -40,43 +69,36 @@ class DoxygenPlugin(Component): def get_active_navigation_item(self, req): return 'doxygen' + def get_navigation_items(self, req): if req.perm.has_permission('DOXYGEN_VIEW'): - # Get config variables. - title = self.env.config.get('doxygen', 'title', 'Doxygen') - # Return mainnav buttons. - yield 'mainnav', 'doxygen', Markup('%s' % \ - (self.env.href.doxygen() + '/', title)) + yield 'mainnav', 'doxygen', \ + html.a(self.title, href=req.href.doxygen()) }}} For more details, refer to the [source:trunk/trac/util/html.py@head#L324 Element] docstring. == Interface Changes == === `ISearchSource` ^[source:trunk/trac/Search.py@head#L30 (0.10)] [source:branches/0.9-stable/trac/Search.py@head#L29 (0.9)]^ === #ISearchSource The `get_search_results(self, req, terms, filters)` now takes a list of `terms` instead of the full `query`, as it used to do for its second argument. Example: (from the [trachacks:DoxygenPlugin]) {{{ #!diff --- doxygentrac/doxygentrac.py Tue Aug 29 14:03:33 2006 +0200 +++ doxygentrac/doxygentrac.py Tue Aug 29 14:04:10 2006 +0200 @@ -212,13 +212,9 @@ yield('doxygen', title) - def get_search_results(self, req, query, filters): + def get_search_results(self, req, keywords, filters): if not 'doxygen' in filters: return - if query[0] == query[-1] == "'" or query[0] == query[-1] == '"': - keywords = [query[1:-1]] - else: - keywords = query.split(' ') base_path = self.config.get('doxygen', 'path') }}} === `IHTMLPreviewRenderer` ^[source:trunk/trac/mimeview/api.py@head#L237 (0.10)] [source:branches/0.9-stable/trac/mimeview/api.py@head#L154 (0.9)]^ === The `render` method has changed. See r3124 for details. Note however that this API is being deprecated, and will be superseded in 0.11 by the `IContentConverter` (see #3332). ---- See also: ["TracDev/ReleaseNotes/0.10"]