| 1 | == Extension Point : ''ISearchSource'' == |
| 2 | |
| 3 | ||'''Interface'''||''ISearchSource''||'''Since'''||0.9|| |
| 4 | ||'''Module'''||''trac.search''||'''Source'''||[source:trunk/trac/search/api.py api.py]|| |
| 5 | |
| 6 | The ''ISearchSource'' allows extending the search system with additional information sources. |
| 7 | |
| 8 | == Purpose == |
| 9 | |
| 10 | Trac provides a unified [TracSearch search system] for full-text search in any resources. By default it supports searching tickets, wiki pages, changesets and milestones. |
| 11 | However plugins can implement arbitrary search sources allowing the user to search its resources or any other data of interest. |
| 12 | |
| 13 | == Usage == |
| 14 | |
| 15 | Implementing the interface follows the standard guidelines found in [wiki:TracDev/ComponentArchitecture] and of course [wiki:TracDev/PluginDevelopment]. |
| 16 | |
| 17 | The implementation reports the supported filters and whether they should be enabled by default. It is then called when a user performs a search, and should return any results matching the search terms for any relevant enabled filters. |
| 18 | |
| 19 | The `trac.search.api` module also provides some helper functions that can often be used to implement the search itself (`search_to_sql`) or to format the results appropriately (`shorten_result`). |
| 20 | |
| 21 | == Examples == |
| 22 | |
| 23 | The following example implements a simple search source for user names. (Note that Trac stores names of authenticated users in the `sid` field of the `session` table.) |
| 24 | {{{ |
| 25 | #!python |
| 26 | from datetime import datetime |
| 27 | from trac.core import * |
| 28 | from trac.search import ISearchSource, search_to_sql |
| 29 | from trac.util.datefmt import utc |
| 30 | |
| 31 | class UserSearchModule(Component): |
| 32 | """Search user names.""" |
| 33 | |
| 34 | implements(ISearchSource) |
| 35 | |
| 36 | # ISearchSource methods |
| 37 | |
| 38 | def get_search_filters(self, req): |
| 39 | yield ('usernames', 'User Names', False) |
| 40 | |
| 41 | def get_search_results(self, req, terms, filters): |
| 42 | if not 'usernames' in filters: |
| 43 | return |
| 44 | with self.env.db_query as db: |
| 45 | sql_query, args = search_to_sql(db, ['sid'], terms) |
| 46 | |
| 47 | for name, last_visit in db(""" |
| 48 | SELECT sid, last_visit FROM session |
| 49 | WHERE authenticated=1 AND """ + sql_query, args): |
| 50 | dt = last_visit if last_visit else datetime.now(utc) |
| 51 | args = '?owner=%s&or&reporter=%s' % (name, name) |
| 52 | link = req.href.query() + args |
| 53 | yield (link, name, dt, '', '') |
| 54 | }}} |
| 55 | |
| 56 | In this example the search result consists simply of a title (the matching name), a date (when the user last visited this Trac instance) and a query link (tickets owned or reported by that user). |
| 57 | |
| 58 | More traditional implementations would show resources as search results, with title (retrieved by `get_resource_name`), URL (`get_resource_url`), excerpt (`shorten_result`) and possibly an author and creation date. |
| 59 | |
| 60 | Often such implementations would also perform ''permission checks'' (and possibly implement [../trac.perm.IPermissionRequestor IPermissionRequestor]). The user might not have permission to search the subsystem at all, or certain individual search results (resources) might need to be filtered out. |
| 61 | |
| 62 | The [source:trunk/trac/ticket/roadmap.py milestone search] is a good example for all of the above. |
| 63 | |
| 64 | == Available Implementations == |
| 65 | In Trac: |
| 66 | || [source:trunk/trac/ticket/web_ui.py TicketModule] || Searches ticket text fields and attachments. || |
| 67 | || [source:trunk/trac/wiki/web_ui.py WikiModule] || Searches wiki pages and attachments. || |
| 68 | || [source:trunk/trac/versioncontrol/web_ui/changeset.py ChangesetModule] || Searches changesets (in the repository cache). || |
| 69 | || [source:trunk/trac/ticket/roadmap.py MilestoneModule] || Searches milestone name, description and attachments. || |
| 70 | |
| 71 | In third-party plugins: |
| 72 | || th:SearchAllPlugin || Searches all Trac projects in the Trac multi-project environment. || |
| 73 | || th:RepoSearchPlugin || Searches the source code repository (using a custom indexer). || |
| 74 | || th:FilenameSearchPlugin || Searches filenames in the source code repository. || |
| 75 | || th:SearchAttachmentsPlugin || Searches attachments (using the ''Swish-e'' indexer). || |
| 76 | || th:TracFormsPlugin || Provides (searchable) Forms anywhere on Trac. || |
| 77 | || th:DoxygenPlugin || Integrates (searchable) doxygen documentation. || |
| 78 | || th:PyDocPlugin || Integrates (searchable) pydoc documentation. || |
| 79 | |
| 80 | == Additional Information and References == |
| 81 | * [http://www.edgewall.org/docs/trac-trunk/epydoc/trac.search.api.ISearchSource-class.html Epydoc API Reference] |
| 82 | * See TracSearch for user documentation of the search system |
| 83 | * See AdvancedSearch for possible improvements |
| 84 | * [/query?status=!closed&component=search+system Related tickets] |
| 85 | |
| 86 | ==== API History ==== |
| 87 | * 0.9 introduced the interface. |
| 88 | * [wiki:TracDev/ApiChanges/0.10#ISearchSource 0.10] changed parameter `query` string to list of `terms`. ([2940]; [th:changeset:459 example] supporting both APIs) |
| 89 | * [wiki:TracDev/ApiChanges/0.11#ISearchSource 0.11] refactored `trac.Search` module into `trac.search` package. ([4262]) |