PKI|68DîÓ––README= Wiki Content Negotiation System = This plugin provides content negotiation mechanism for Trac wiki pages. With this plugin, your trac site can provides localized pages for users. Content negotiation is a commonly used mechanism in modern http servers to select a page to serve by regarding to 'Accept-Language:' header in http request. You can provide multi-language page with single url. For example, the plugin check the request header and tells Trac to render `WikiStart.ja` instead of `WikiStart` for URL `http://www.sample.org/trac/wiki/WikiStart`. This example mentioned about only Japanese, multiple languages can be served, of course. Thus, what you should do is a writing a localized contents. Enjoy! == How to Install == Build egg file and place it appropriate place If you want to install as system wide plugin: {{{ $ python setup.py install }}} If you want to build plugin egg file and use it in some projects, build egg file and copy it into `plugins` directory under the trac environment directory: {{{ $ python setup.py bdist_egg ... $ cp dist/*.egg /your/trac/project/plugins }}} == How to Setup == On using this plugin, do not forget enabling plugin `WikiNegotiator` in `trac.ini` or via `WebAdmin` page. {{{ [components] tracnegotiator.* = enabled [wiki] default_language = en }}} == How to Use === Using the negotiation feature is simply providing suffixed page like 'Foo.ja' for Japanese, 'Foo.fr' for French, so on. When Japanese user (with Japanese setting in browser) access to the page 'Foo', he will see the content of `Foo.ja` instead of `Foo`. Likewise, French use will see the content of `Foo.fr`. So what you should to do is creating localized page content as usual way. Note that suffix like '.ja' and '.fr' is to be a standard language code. Non-suffixed page `Foo` is also usable for default content when no suffixed page is matched to user's request. To see the page for your language, nothing to do to view localized page. To see the page for other language, specify the appropreate suffix for wiki page name in url explicitly, or add query parameter like "?lang=xx". To edit the page, you can edit the page now you are seeing by simply press "Edit" button. To edit the page for other language, first, visit the desired page with a way described above, then press "Edit" button. == Bonus Macro == For bonus, this plugin contains one new macro: `MultiLangTitleIndex`. This is alternative macro of `TitleIndex`. The difference of two are: * Display in one line for variants like: "* WikiStart (ja, en, other)". * List pages in two columns: one is for user's pages, one is for system provided pages. System pages are the pages made by trac. `WikiStart` and `SandBox` are exception by default because it is a page to be edited by user. It is useful for the site having many localized pages. You can use it by editing `TitleIndex` page. == How it Works == This mechanism is implemented by replacing target page name before processing via `pre_process_request()` hook provided by `IRequestFilter`. This entry point can be used on Trac 0.10 or later. The point of this feature is a page naming rule of language suffix. For example, `WikiStart.ja` page means "WikiStart page for Japanese". When you accessed to non-suffixed page (like `WikiStart`), negotiation is enabled. The plugin make a list of acceptable languages for user from `lang=xx` query parameter, from `Accept-Language` in http request and from `default_wiki_lang` option. If no matching variant is exist, non-suffixed page is used. When you access to obviously suffixed page name, negotiation is disabled and spcified page is used. The `default_wiki_lang` option can be specified in `trac.ini`. The defeault is "en". This value is weak language code for non-suffed page. This means the page `Foo` will substitute for `Foo.en` when the page `Foo.en` is not exist. For example, if user have language setting of browser as Japanese (ja) as primary language and English (en) as secondary, accessing to page `Foo` goes like this: 1. Enable negotiation because accessing to non-suffixed page. 2. Use language xx if `lang=xx` query parameter is specified. Or make list of preferred languages from `Accept-Language:`. 3. Find variant of `Foo` matching in preferred language. At this time, if suffixed page for default language is not exist, non-suffixed page is used as for the language. 4. If it cannot be decided the page in step 3, non-suffixed page is used as "default page for any other languages". Here are more examples to explain the behaviour of this plugin. Example 1: If user preferred 'ja' then 'en', the pages 'Foo' and 'Foo.fr' is exist, request to 'Foo' handles contents of 'Foo.ja'. Example 2: If user preferred 'ja' then 'en', the pages 'Foo', 'Foo.ja' and 'Foo.fr' is exist, request to 'Foo.fr' handles contents of 'Foo.fr' because negotiation is disabled to access for suffixed page. Example 3: If user preferred 'ja' then 'en', the pages 'Foo' and 'Foo.fr' is exist, request to 'Foo' with 'lang=fr' parameter, the wiki module handles contents of 'Foo.fr' because language is specified explicitly and overrides preffered languages. Example 4: If user preferred 'ja' then 'en', the pages 'Foo' and 'Foo.fr' is exist, and default language is 'en', 'Foo' is used because 'Foo' is treated as 'Foo.en'. Example 5: If user preferred 'ja' then 'en', the pages 'Foo', 'Foo.en' and 'Foo.fr' is exist, and default language is 'en', 'Foo.en' (not 'Foo') is used because 'Foo.en' is exst. Example 6: If user preferred 'ja' then 'en', the pages 'Foo', 'Foo.en' and 'Foo.fr' is exist, and requested with 'lang=other' query parameter, 'Foo' is used because language 'other' is not matched with any variants. Example 7: In special notation, access to the page 'Foo.' (with dot on the tail) disables negotiation and handles contents of 'Foo' (without dot). This is equiv to the case with 'lang=' (empty lang name) query parameter. PKâ…68“×2EGG-INFO/zip-safe PKÚ…68@ ›66EGG-INFO/SOURCES.txtREADME setup.py TracWikiNegotiator.egg-info/PKG-INFO TracWikiNegotiator.egg-info/SOURCES.txt TracWikiNegotiator.egg-info/dependency_links.txt TracWikiNegotiator.egg-info/entry_points.txt TracWikiNegotiator.egg-info/top_level.txt wikinegotiator/__init__.py wikinegotiator/macros.py wikinegotiator/negotiator.py PKÙ…68…Ä44EGG-INFO/entry_points.txt[trac.plugins] TracWikiNegotiator = wikinegotiator PKÙ…68“×2EGG-INFO/dependency_links.txt PKÙ…68CñXöÐÐEGG-INFO/PKG-INFOMetadata-Version: 1.0 Name: TracWikiNegotiator Version: 1.0 Summary: Content negotiation plugin for Trac wiki page. Home-page: UNKNOWN Author: Shun-ichi Goto Author-email: shunichi.goto@gmail.com License: BSD Description: This plugin provides content negotiation mechanism for Trac wiki pages. With this plugin, the trac site can provides localized pages for users. Keywords: trac plugin localization l10n wiki Platform: UNKNOWN PKÙ…68ÇåùEGG-INFO/top_level.txtwikinegotiator PKI|6¢Ã~ÎNNwikinegotiator/__init__.pyfrom negotiator import WikiNegotiator from macros import MultiLangTitleIndex PKÜ…68$Þ›wikinegotiator/negotiator.pyc;ò é Fc@s„dkZdklZdklZlZdklZdklZdk l Z dk l Z dk lZdefd „ƒYZdS( N(surlparse(s Components implements(s WikiSystem(s WikiModule(sIRequestFilter(sOption(sMultiLangTitleIndexsWikiNegotiatorcBs…tZeidƒZeiddƒZedddddƒZee ƒd „Z d „Z d „Z e d „Zd „Zd„ZRS(Ns'(.*)(?:\.([a-z][a-z](?:-[a-z][a-z])?))$s(^(?P[a-z]{1,8}(?:-[a-z]{1,8})?|\*)s(?:;\s*q=(?P[0-9.]+))?$swikis default_langsensdocsLanguage for non-suffixed page.cCs´t|tƒoœ|iiddƒ}|i|ƒ}||joW||id<|i i i d|ƒ|i |ƒ\}}|id|p|iƒn|iddƒn|SdS(soReplace requested wiki page name by content negotiation. Nothing changed for non-wiki request. spages WikiStartsNegotiated: %ssContent-LanguagesVarysAccept-LanguageN(s isinstanceshandlers WikiModulesreqsargssgetsorigsselfs _decide_pagespagesenvslogsdebugs _split_langs_slangs send_headers _default_lang(sselfsreqshandlerslangspages_sorig((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pyspre_process_requests   cCs||fSdS(N(stemplates content_type(sselfsreqstemplates content_type((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pyspost_process_request2scCse|iiddƒ}|iidtƒo|Sn|idƒ}|o0|i|iƒodt |ƒdi dƒjo|i i idƒ|Sn|id ƒo |d Sn|i|ƒ\}}|o|Sn|pd}t|i ƒ}xg|i|ƒD]V}d ||f}|i|ƒo|Sn||ijo |i|ƒo|SqqW|Sd S( s²decide page name to use regarding client language. This function is called from hook with self as WikiModule instance. Returns page name to be displayed. spages WikiStartsactionsReferers action=editis&s$disable negotiation for edited page.s.iÿÿÿÿs%s.%sN(sreqsargssgetsorigsNones get_headersreferers startswithsbase_urlsurlparsessplitsselfsenvslogsdebugsendswiths _split_langspageslangs WikiSystemswikis_get_preferred_langsslpageshas_pages _default_lang(sselfsreqslangswikisrefererslpagespagesorig((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pys _decide_page9s.:    cCsG|ii|ƒ}|o |idƒ|idƒfSn ||fSdS(sÐSplit page body name and suffixed language code from requested page name. ex. 'sub/pagename.ja' => ('sub/pagename', 'ja') 'sub/pagename.ja-jp' => ('sub/pagename', 'ja-jp') iiN(sselfs_re_pagesmatchspagesmsgroupslang(sselfspageslangsm((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pys _split_langws  cCsx|iidƒo|iidƒgSn|i|idƒp|iƒ}|i|jo||ig7}n|SdS(Nslangsaccept-language( sreqsargsshas_keysgetsselfs _parse_langss get_headers _default_langslangs(sselfsreqslangs((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pys_get_preferred_langs„s "c Cs²g}xl|idƒD][}|ii|iƒƒ}|o6|i ƒ\}}|i |t |pdƒfƒqqW|id„ƒgi }|D]}||dƒq“~SdS(sÞMake list of language tag in preferred order. For example, Accept-Language: ja,en-us;q=0.8,en;q=0.2 or Accept-Language: en;q=0.2,en-us;q=0.8,ja results ['ja', 'en-us', 'en'] s,s1.0cCst|d|dƒS(Ni(scmpsysx(sxsy((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pysŸsiN(sinfossalssplitsitemsselfs_re_langsmatchsstripsmsgroupsslangsqsappendsfloatssorts_[1]sinfo( sselfsalslangs_[1]smsqsitemsinfosinfos((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pys _parse_langss((s__name__s __module__srescompiles_re_pages_re_langsOptions _default_langs implementssIRequestFilterspre_process_requestspost_process_requests _decide_pagesNones _split_langs_get_preferred_langss _parse_langs(((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pysWikiNegotiator s      > (sresurlparses trac.cores Components implementss trac.wikis WikiSystemstrac.wiki.web_uis WikiModules trac.web.apisIRequestFilters trac.configsOptionsmacrossMultiLangTitleIndexsWikiNegotiator( s implementssOptionsMultiLangTitleIndexsIRequestFilters Componentsurlparsesres WikiModulesWikiNegotiators WikiSystem((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pys?s       PKà…688hYLLwikinegotiator/__init__.pyo;ò åh Fc@sdklZdklZdS((sWikiNegotiator(sMultiLangTitleIndexN(s negotiatorsWikiNegotiatorsmacrossMultiLangTitleIndex(sWikiNegotiatorsMultiLangTitleIndex((s;build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/__init__.pys?s PK—6 QlŒwikinegotiator/negotiator.py# -*- coding: utf-8 -*- import re from urlparse import urlparse from trac.core import Component, implements from trac.wiki import WikiSystem from trac.wiki.web_ui import WikiModule from trac.web.api import IRequestFilter from trac.config import Option from macros import MultiLangTitleIndex class WikiNegotiator(Component): _re_page = re.compile(r'(.*)(?:\.([a-z][a-z](?:-[a-z][a-z])?))$') _re_lang = re.compile(r'^(?P[a-z]{1,8}(?:-[a-z]{1,8})?|\*)' +'(?:;\s*q=(?P[0-9.]+))?$') _default_lang = Option('wiki', 'default_lang', 'en', doc="""Language for non-suffixed page.""") implements(IRequestFilter) # -- implementation of IRequestFilter -- def pre_process_request(self, req, handler): """Replace requested wiki page name by content negotiation. Nothing changed for non-wiki request. """ if isinstance(handler, WikiModule): orig = req.args.get('page', 'WikiStart') # set altered page name page = self._decide_page(req) if page != orig: req.args['page'] = page self.env.log.debug('Negotiated: %s' % page) # Set Content-Language only when language specific # page is selected. # TODO: I don't know we should set default language # for base page. _, lang = self._split_lang(page) req.send_header('Content-Language', lang or self._default_lang) # always send Vary header to tell language negitiation is # available req.send_header('Vary', 'Accept-Language') return handler def post_process_request(self, req, template, content_type): # nothing to do return template, content_type # local methods def _decide_page(self, req): """decide page name to use regarding client language. This function is called from hook with self as WikiModule instance. Returns page name to be displayed. """ orig = req.args.get('page', 'WikiStart') # This negotiation is only for viewing. # If without this rule, you may edit 'SomePage.en' by edit # button on 'SomePage.' page. if req.args.get('action', None): return orig # No negotiation to display edited page after commit. # 'Referrer' header can be used to detect this case # by checking 'action=edit' parameter. # ex. "Referer: http://host/wiki/WikiStart?action=edit" referer = req.get_header('Referer') if referer and referer.startswith(req.base_url) and \ 'action=edit' in urlparse(referer)[4].split('&'): self.env.log.debug('disable negotiation for edited page.') return orig # Use requested page itself if the page name has language # suffix. As special case, if the name ends with period '.', # use non-suffixed page is used. if orig.endswith('.'): return orig[:-1] # force un suffixed page page, lang = self._split_lang(orig) if lang: #debug('case 1 : requested page name has lang suffix') return orig page = page or 'WikiStart' # At this point, page name does not have language suffix. # List preffered language codes from http request. # Check language suffixed page existance in order of preffered # language codes in http request and use it if exist. wiki = WikiSystem(self.env) for lang in self._get_preferred_langs(req): lpage = '%s.%s' % (page, lang) if wiki.has_page(lpage): #debug('case 2 : have suffixed page: %s' % lpage) return lpage # Consideration of default_lang setting. # This is required not access to lower ordered # language page. For example, # preferred language: ja, en, fr # default_lang: en # existing pages: 'page', 'page.fr' # We should search page in order: # 'page.ja', 'page.en', 'page', 'page.fr' if lang == self._default_lang and wiki.has_page(page): return page # No page matched with preffered language. # Use requested page. #debug('case 3 : no page for preffered lang') return orig def _split_lang(self, page, lang=None): """Split page body name and suffixed language code from requested page name. ex. 'sub/pagename.ja' => ('sub/pagename', 'ja') 'sub/pagename.ja-jp' => ('sub/pagename', 'ja-jp') """ m = self._re_page.match(page) if m: return (m.group(1), m.group(2)) # with lang suffix else: return (page, lang) # without lang suffix def _get_preferred_langs(self, req): # decide by language denotation in url parameter: '?lang=xx' if req.args.has_key('lang'): return [req.args.get('lang')] # otherwise, decide by http Accept-Language: header langs = self._parse_langs(req.get_header('accept-language') or self._default_lang) if self._default_lang not in langs: langs += [self._default_lang] # fallback language return langs def _parse_langs(self, al): """Make list of language tag in preferred order. For example, Accept-Language: ja,en-us;q=0.8,en;q=0.2 or Accept-Language: en;q=0.2,en-us;q=0.8,ja results ['ja', 'en-us', 'en'] """ infos = [] for item in al.split(','): m = self._re_lang.match(item.strip()) if m: lang, q = m.groups() infos.append((lang, float(q or '1.0'))) # sort by quality descendant infos.sort(lambda x,y: cmp(y[1], x[1])) return [info[0] for info in infos] # returns list of lang string PKà…68p¶¶wikinegotiator/macros.pyo;ò é Fc@spdkZdkTdklZlZlZdklZdkl Z l Z dk l Z de fd„ƒYZ dS(N(s*(sOptions ListOptions BoolOption(ssorted(s WikiSystemshtml(s WikiMacroBasesMultiLangTitleIndexcBs/tZdZedddddƒZd„ZRS(sºInserts an alphabetic list of all wiki pages cosidering suffixes. This macro is similar to TitleIndex macro but differ in two points. * All the variants are displayed in one line. * Displayed in two columns. One is for the pages made for the project. One is for the pages provided by Trac. `WikiStart` and `SandBox` are grouped in project pages as default. This is configurable via `_explicit_user_pages` option. One entry displayed by this macro has a format like this: {{{ WikiStart (en, fr, ja, other) }}} Left most page name is for usual access with negotiation. Items in paren are existing language variants for the page. smulti-lang-title-indexsexplicit_user_pagessWikiStart, SandBoxsdocs.List of page names to be grouped in user page.c Csä|i} | iƒ}|iƒ}|idƒg} h}t i dƒ}xŸ|D]—\}} |i|ƒ}|oJ|iƒ\}}|i|gƒ}||jo||g||[a-z]{1,8}(?:-[a-z]{1,8})?|\*)s(?:;\s*q=(?P[0-9.]+))?$swikis default_langsensdocsLanguage for non-suffixed page.cCs´t|tƒoœ|iiddƒ}|i|ƒ}||joW||id<|i i i d|ƒ|i |ƒ\}}|id|p|iƒn|iddƒn|SdS(soReplace requested wiki page name by content negotiation. Nothing changed for non-wiki request. spages WikiStartsNegotiated: %ssContent-LanguagesVarysAccept-LanguageN(s isinstanceshandlers WikiModulesreqsargssgetsorigsselfs _decide_pagespagesenvslogsdebugs _split_langs_slangs send_headers _default_lang(sselfsreqshandlerslangspages_sorig((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pyspre_process_requests   cCs||fSdS(N(stemplates content_type(sselfsreqstemplates content_type((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pyspost_process_request2scCse|iiddƒ}|iidtƒo|Sn|idƒ}|o0|i|iƒodt |ƒdi dƒjo|i i idƒ|Sn|id ƒo |d Sn|i|ƒ\}}|o|Sn|pd}t|i ƒ}xg|i|ƒD]V}d ||f}|i|ƒo|Sn||ijo |i|ƒo|SqqW|Sd S( s²decide page name to use regarding client language. This function is called from hook with self as WikiModule instance. Returns page name to be displayed. spages WikiStartsactionsReferers action=editis&s$disable negotiation for edited page.s.iÿÿÿÿs%s.%sN(sreqsargssgetsorigsNones get_headersreferers startswithsbase_urlsurlparsessplitsselfsenvslogsdebugsendswiths _split_langspageslangs WikiSystemswikis_get_preferred_langsslpageshas_pages _default_lang(sselfsreqslangswikisrefererslpagespagesorig((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pys _decide_page9s.:    cCsG|ii|ƒ}|o |idƒ|idƒfSn ||fSdS(sÐSplit page body name and suffixed language code from requested page name. ex. 'sub/pagename.ja' => ('sub/pagename', 'ja') 'sub/pagename.ja-jp' => ('sub/pagename', 'ja-jp') iiN(sselfs_re_pagesmatchspagesmsgroupslang(sselfspageslangsm((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pys _split_langws  cCsx|iidƒo|iidƒgSn|i|idƒp|iƒ}|i|jo||ig7}n|SdS(Nslangsaccept-language( sreqsargsshas_keysgetsselfs _parse_langss get_headers _default_langslangs(sselfsreqslangs((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pys_get_preferred_langs„s "c Cs²g}xl|idƒD][}|ii|iƒƒ}|o6|i ƒ\}}|i |t |pdƒfƒqqW|id„ƒgi }|D]}||dƒq“~SdS(sÞMake list of language tag in preferred order. For example, Accept-Language: ja,en-us;q=0.8,en;q=0.2 or Accept-Language: en;q=0.2,en-us;q=0.8,ja results ['ja', 'en-us', 'en'] s,s1.0cCst|d|dƒS(Ni(scmpsysx(sxsy((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pysŸsiN(sinfossalssplitsitemsselfs_re_langsmatchsstripsmsgroupsslangsqsappendsfloatssorts_[1]sinfo( sselfsalslangs_[1]smsqsitemsinfosinfos((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pys _parse_langss((s__name__s __module__srescompiles_re_pages_re_langsOptions _default_langs implementssIRequestFilterspre_process_requestspost_process_requests _decide_pagesNones _split_langs_get_preferred_langss _parse_langs(((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pysWikiNegotiator s      > (sresurlparses trac.cores Components implementss trac.wikis WikiSystemstrac.wiki.web_uis WikiModules trac.web.apisIRequestFilters trac.configsOptionsmacrossMultiLangTitleIndexsWikiNegotiator( s implementssOptionsMultiLangTitleIndexsIRequestFilters Componentsurlparsesres WikiModulesWikiNegotiators WikiSystem((s=build/bdist.darwin-8.0.1-x86/egg/wikinegotiator/negotiator.pys?s       PK—64 —²ÛÛwikinegotiator/macros.py# -*- coding: utf-8 -*- import re from trac.core import * from trac.config import Option, ListOption, BoolOption from trac.util import sorted from trac.wiki import WikiSystem, html from trac.wiki.macros import WikiMacroBase ## macro class MultiLangTitleIndex(WikiMacroBase): """Inserts an alphabetic list of all wiki pages cosidering suffixes. This macro is similar to TitleIndex macro but differ in two points. * All the variants are displayed in one line. * Displayed in two columns. One is for the pages made for the project. One is for the pages provided by Trac. `WikiStart` and `SandBox` are grouped in project pages as default. This is configurable via `_explicit_user_pages` option. One entry displayed by this macro has a format like this: {{{ WikiStart (en, fr, ja, other) }}} Left most page name is for usual access with negotiation. Items in paren are existing language variants for the page. """ _explicit_user_pages = ListOption('multi-lang-title-index', 'explicit_user_pages', 'WikiStart, SandBox', doc="List of page names to be grouped" " in user page.") def render_macro(self, req, name, content): # get system pages which is author=trac at version 1 env = self.env db = env.get_db_cnx() curs = db.cursor() # Pick pages whose author is 'trac' in some version. This means # that the system page modified by user is grouped as 'system # page'. curs.execute("select name,author from wiki") system_pages = [] # pages marked as system's lang_map = {} # language list for each page re_lang = re.compile('^(.*)\.([a-z]{2}(?:-[a-z]{2})?)$') for page, author in curs: # note: language variant is not stored in system_pages. m = re_lang.match(page) if m: p, l = m.groups() langs = lang_map.get(p,[]) if l not in langs: lang_map[p] = langs + [l] elif author == 'trac' and page not in system_pages: system_pages.append(page) if not hasattr(env, 'get_cnx_pool'): # without db connection pool, we should close db. curs.close() db.close() # Exclude some pages to be grouped in user page. for page in self._explicit_user_pages: if page in system_pages: system_pages.remove(page) # Pick user pages. Specially for language variation pages, # translated page of system page is also grouped as system page as # if author is not 'trac'. This is for shrinked view. re_sys = re.compile('^(?:' + '|'.join(system_pages) + '(?:\.[a-z]{2}(?:-[a-z]{2})?)?)') prefix = content or None wiki = WikiSystem(env) user_pages = [] # pages marked as user's pages = list(wiki.get_pages(prefix)) for page in lang_map.keys(): # register base page despite of eixstance if page not in pages: pages.append(page) for page in sorted(pages): if re_lang.match(page): continue if not re_sys.match(page): user_pages.append(page) ## should be langu sub item'ed tr = html.TR(valign='top') for title, pages in (('Project', user_pages), ('System Provided', system_pages)): if 0 < len(pages): td = html.TD tr.append(td) if not prefix: td.append(html.B(title + ' Pages')) ul = html.UL() td.append(ul) for page in sorted(pages): item = [html.A(wiki.format_page_name(page), href=env.href.wiki(page))] if lang_map.has_key(page): item.append(' (') langs = lang_map[page] for lang in sorted(langs) + ['other']: p = '%s.%s' % (page, lang) item.append(html.A(lang, href=env.href.wiki(page) + '?lang='+lang, style='color:#833' )) item.append(', ') item.pop() item.append(')') ul.append(html.LI(item)) return html.TABLE(tr) PKI|68DîÓ––íREADMEPKâ…68“×2¤ºEGG-INFO/zip-safePKÚ…68@ ›66¤êEGG-INFO/SOURCES.txtPKÙ…68…Ä44¤REGG-INFO/entry_points.txtPKÙ…68“×2¤½EGG-INFO/dependency_links.txtPKÙ…68CñXöÐФùEGG-INFO/PKG-INFOPKÙ…68Çåù¤øEGG-INFO/top_level.txtPKI|6¢Ã~ÎNN¤;wikinegotiator/__init__.pyPKÜ…68$Þ›¤Áwikinegotiator/negotiator.pycPKà…688hYLL¤4wikinegotiator/__init__.pyoPK—6 QlŒ¤™5wikinegotiator/negotiator.pyPKà…68p¶¶¤ïMwikinegotiator/macros.pyoPKÛ…688hYLL¤Ü^wikinegotiator/__init__.pycPKÜ…68p¶¶¤a`wikinegotiator/macros.pycPKà…68$Þ›¤Nqwikinegotiator/negotiator.pyoPK—64 —²ÛÛ¤¡ˆwikinegotiator/macros.pyPKX²›