## page was renamed from MoinAPI/BeispieleEng #pragma supplementation-page on #pragma section-numbers on {{{{#!wiki blue '''Preface''' The original text was written in German for a [[http://www.rrzn.uni-hannover.de/buecher.html?&no_cache=1&tx_rrznbuecher_pi1[showUid]=215|book about Python]]<>. Later [[NickDemou|Nick Demou]] made an effort<> to provide a better translation than the [[http://translate.google.com/translate?prev=_t&hl=en&ie=UTF-8&u=http%3A%2F%2Fmoinmo.in%2FMoinAPI%2FBeispiele&sl=de&tl=en&history_state0=|one you get]] by trying a Google Translation of the [[MoinAPI/Beispiele|original German page]]. '''Be warned''' however that most of this text is the ''result of machine translation'' cleaned up by someone who doesn't speak German. If you do speak German we'd love to see you cleaning up bits of this text (an easy way is to enable comments and look for sentences marked with {{{BAD_TRANSLATION}}}). To make it easy to compare this text and the original the few additions have been marked with the comment {{{NEW_TEXT }}} }}}} @copyright: 2007-2012 MoinMoin:ReimarBauer @license: GPL <> == MoinMoin (1.9) - extensions and adaptations (Reimar Bauer) == ##der text der hier hin soll steckt noch im Buch == Introduction == MoinMoin is a wiki software that is written in Python. Currently being developed in version 2.0. - On the homepage ({{{http://moinmo.in}}}), you can find the current state of development. MoinMoin is Free Software (Open Source Software) under the GNU General Public License. This description requires that you download the latest version of the software from the website. A wiki a World Wide Web pages available collection, read by users, not just in real time can be changed is online. As is usual in hypertext, the individual pages and articles of a wiki is by cross-references (links) connected together. Since version 1.6 contains a preconfigured MoinMoin Wiki, which is related to the work contained in the Python standard library web server suitable for a personal wiki on your local desktop. This combination also allows, in a development environment (eg Eclipse / PyDev) to debug comfortable. Therefore, please follow the instructions in the installation instructions for the preconfigured Wiki. This wiki also contains the help pages. Almost anything can be changed to MoinMoin through a sophisticated plug-in concept. You can mount the look of its own ''Theme'' transform (see [[#plugintheme|theme]]). With a ''Parser'' (see [[#pluginparser|parser plugins]] You can interpret and display this content then. A ''Macro'' (see [[#pluginmacro|macro plugins]]) serves as a command to insert a little on one side while having a ''Action'' ( see [[#pluginaction|action plugins]]) determine what should be done to "push". A ''Formatter'' see [[#pluginformatter|formatter plugins]]) and chapter [[#formatter|formatter]] ) allows an output in any format. ''Filter'' ([[#pluginfilter|filter plugins]]) are used to build the search index using the example of file attachments. With ''XMLRPC'' (see [[#xmlrpc|xmlrpc]] and [[#pluginxmlrpc|xmlrpc plugins]]), you can communicate via a network connection with MoinMoin. If you have for improvement, you can create a feature request <> - possibly even a patch if you have already implemented the feature. In this text, all examples refer to the standalone server and preconfigured wiki. <> To start the standalone server, go the directory {{{moin-1.9}}} and call the program {{{wikiserver.py}}}. You can access your wiki localy by visiting the URL ''http://localhost:8080/''. If you want to change settings, you'll find them the configuration file {{{wikiconfig.py}}} which can be found in the same directory (see HelpOnConfiguration). /* NEW_TEXT */ To try the examples in the Python interpreter you should stay in the same directory and start python with a command like {{{sudo -u www-data python}}}. Note that you must ensure that the appropriate user rights are granted. If you're working with a test wiki you can include this line in {{{wikiconfig.py}}}: {{{acl_rights_default = u'All:read,write,delete,revert,admin'}}} But '''NOTE''' that this line lets every user do everything he likes on any page. == Classes and methods of MoinMoin == The following chart <> shows the main classes that serve a wiki page to your browser. The individual classes represent steps of a complete operation. For example a page is requested by an {{{Action}}} {{{request}}}. Then goes through {{{Page}}} and then {{{Theme}}} adds additional content before finaly an HTML page is sent to your browser. <> || {{attachment:MoinAPI/Beispiele/MoinMoinArchitecture.png}} || || Basic construction of MoinMoin || What all these classes have in common is that they communicate via a {{{request}}} object with each other. With its own {{{request}}} object (see [[#request|request]]), you can use from another application MoinMoin to integrate a wiki into your application. /* BAD_TRANSLATION */ It's simple to work with MoinMoin code. I will present to you first some classes from the library, but I can not describe in detail all their methods and parameters. I'll limit myself to those that we will use in our examples. Since you have the source code available, you can still find many other interesting classes and methods. You are welcome to visit the developers in their chat room {{{#moin}}} at {{{chat.freenode.net}}} if something is unclear or you want to discuss further options. The example below shows how you can use some functions to output a page. {{{#!python from MoinMoin.Page import Page from MoinMoin.web.contexts import ScriptContext request = ScriptContext() pagename = u'StartPage' text = Page(request, pagename).get_raw_body() print text }}} First we import {{{Page}}} from class {{{MoinMoin.Page}}} and {{{ScriptContext}}} from class {{{MoinMoin.web.contexts}}}. The {{{Page}}} class (see [[#Page|Page]]), you need read access to a wiki page. The {{{request}}} Object (see [[#request|request]]) you need for all access to the wiki, the place of the Python shell. /* BAD_TRANSLATION */ With {{{request = ScriptContext()}}} the variable {{{request}}} is assigned with a newly created {{{request}}} object. The variable {{{pagename}}} is set to a unicode string ({{{u'StartPage'}}}) which is the name of the page you want to output. The following line {{{text = Page(request, pagename).get_raw_body()}}} calls method {{{get_raw_body}}} from class {{{Page}}} (see [[#pagegetrawbody|page.get_raw_body]]). This reads the content of the page in {{{text}}}. With {{{print text}}} the content of {{{text}}} are displayed. <> === request === The {{{request}}} object is central and conects all the classes (see [[#Schaubild|figure]]) together. This contains data and objects that are required in many parts of the code, including access to the configuration file. /* BAD_TRANSLATION */ Besides the {{{request}}} object ({{{ScriptContext}}}), you can use to work in the Python shell, MoinMoin also supports {{{cgi}}}, {{{fcgi}}}, {{{standalone}}}, {{{twisted}}} and {{{wsgi}}} (see HelpOnInstalling) . MoinMoin since version 1.9 is a WSGI application and uses the [[http://werkzeug.pocoo.org/|werkzeug]] library. All other deployment methods are implemented by the middleware [[http://trac.saddi.com/flup|flup]]. Very practical while learning is to use the {{{request}}} object in the Python shell, many of the methods for the plug-in development (see [[#Plugins|Plugins]]) are important, and know. /* BAD_TRANSLATION */ If you already have an application developed in Python, you can communicate with others with this {{{request}}} object with a MoinMoin wiki or use the wiki functionality. The following example shows how you can make a {{{request}}} object from the Python Shell, and how you can access the wiki from the shell. {{{#!python from MoinMoin.web.contexts import ScriptContext request = ScriptContext() }}} You can contact {{{help(request)}}} the docstrings of {{{request}}}. The docstring begins with the following text: {{{ Help on ScriptContext in module MoinMoin.web.contexts object: class ScriptContext(AllContext) | Context to act in scripting environments (e.g. former request_cli). | | For input, sys.stdin is used as 'wsgi.input', output is written directly | to sys.stdout though. | | Method resolution order: | ScriptContext | AllContext | HTTPContext | BaseContext | Context | AuxilaryMixin | __builtin__.object }}} ==== request.getText ==== The method {{{request.getText}}} enables the translation of text (eg the caption of the navigation elements) in the default language of the user. {{{#!python request.lang = 'de' _ = request.getText print _("Mail me my account data") }}} Outputs: {{{ E-Mail mit den Zugangsdaten senden }}} MoinMoin is developed in English and translates the text into the current user language. See ''moin-1.9/MoinMoin/i18n'' in the file ''de.!MoinMoin.po'' the German translations. Possibly. found in this file there an appropriate output text for your extension. Then you can directly benefit from the existing translations. The translation work is jointly carried out by many users on the wiki [[MoinMaster:AktuelleƄnderungen|MoinMaster]] <>. This wiki is also the development of the help pages, you'll find in your wiki. If you want to help with translations, you should just try out the action [[http://master19.moinmo.in/?action=CheckTranslation|CheckTranslation]]. So you can get an overview of what needs to be translated. <> ==== request.dicts ==== The methods of the class {{{wiki_dicts}}} gives you access to dictionaries that corespond to Wiki pages. You can use a dictionary to process variables as they create will be used in {{{dicts}}}. They allow you to define each with a key to one or more values (see HelpOnDictionaries). There are several ways to create dicts. Currently you can create dicts as a wiki page or in the wikiconfig. These are also vereinigbar (CompositeDicts). /* BAD_TRANSLATION */ The following is an excerpt from `moin-1.9/wiki/config/more_samples/dicts_wikiconfig_snippet`. /* HelpOnConfiguration */ This is an example of how to define the wikiconfig in the dictionary. The default is to map dictionaries from wiki pages. {{{#!python def dicts(self, request): from MoinMoin.datastruct import ConfigDicts dicts = {u'OneDict': {u'first_key': u'first item', u'second_key': u'second item'}, u'NumbersDict': {u'1': 'One', u'2': 'Two'}} return ConfigDicts(request, dicts) }}} Access to the dicts via the `request.dicts`. In {{{HelpOnConfiguration}}} variable {{{page_dict_regex}}} is described. With the variable {{{page_dict_regex}}} you determine which pages are considered as {{{wiki_dicts}}}. The default is: {{{ page_dict_regex = ur'(?P(?P\S+)Dict)' }}} If for example you create a page with the name `http://localhost:8080/BeispielDict` and then create an example of a definition list /* (HelpOnLists) */. {{{ var:: This is an example }}} Then you can access to the variable var in the dictionary as follows: {{{#!python pagename = u"BeispielDict" d = request.dicts.get(pagename, {}) print d.items() print d["var"] }}} output: {{{ [(u'var', u'this is an example')] this is an example }}} The macro `GetVal` applies this method. You can use the {{{Wert}}} insert anywhere where you write the macro `<>` in wiki text. This variable can be used also by any other wiki page. (see HelpOnVariables) ==== request.groups ==== The definition of the variable {{{page_group_regex}}} determines which pages are being evaluated as a group. In general, such sites for the definition of user groups are used. (see HelpOnAccessControlLists) These groups are then used to grant privileges on wiki pages. But this is not limited. All types of items can be grouped together with group pages. The default is: {{{ page_group_regex = ur'(?P(?P\S+)Group)' }}} In addition to the default setting to use the wiki pages, you can set wikiconfig in the definition by a different method. The following is an excerpt from `moin-1.9/wiki/config/more_samples/groups_wikiconfig_snippet`. /* HelpOnConfiguration */ {{{#!python # ConfigGroups uses groups defined in the configuration file. def groups(self, request): from MoinMoin.datastruct import ConfigGroups # Groups are defined here. groups = {u'EditorGroup': [u'AdminGroup', u'John', u'JoeDoe', u'Editor1'], u'AdminGroup': [u'Admin1', u'Admin2', u'John']} return ConfigGroups(request, groups) }}} Using composite groups you can combine several methods. Access to the groups by means of `request.groups`. Make sure you have to test a page with the name `http://localhost:8080/FruitsGroup' on and there a bulleted list /* (HelpOnLists) */ with the items, such as: {{{ * Aple * Orange * Banana }}} Now you can easily see what's in the fruit group and what's not. {{{#!python groups = request.groups fruits = groups.get('FruitsGroup') print u'Apple' in fruits for item in fruits: print item }}} output: {{{ True Apple Orange Banana }}} Please note that groups may contain other groups and quite a lot of items, so a list of items does not necessarily make sense. <> ==== request.user.may ==== Using the methods of {{{request.user.may}}} one can check what rights a user has on a specific page. {{{#!python pagename = u'StartPage' print request.user.may.read(pagename) print request.user.may.write(pagename) print request.user.may.delete(pagename) print request.user.may.revert(pagename) print request.user.may.admin(pagename) }}} <> === Page === The class {{{Page}}} is used for {{{readonly}}} access to a page. It also allows you to access older versions of a page. For operations on wiki pages or any of their attachments, the user's access rights are checked (see HelpOnAccessControlLists). {{{#!python from MoinMoin.Page import Page }}} ==== Page.exists() ==== The method {{{Page.exists()}}} is for determining if a page already exists, for example: {{{#!python pagename = u'StartPage' print Page(request, pagename).exists() }}} output: {{{ True }}} ==== Page.getRevList() ==== The method {{{Page.getRevList()}}} gives a list of older versions of a page. The current version is shown first. {{{#!python pagename = u'StartPage' print Page(request, pagename).getRevList() }}} output: {{{ [1] }}} ==== Page.current_rev() ==== The method {{{Page.current_rev()}}} shows the current revision of a page. {{{#!python pagename = u'StartPage' print Page(request, pagename).current_rev() }}} output: {{{ 1 }}} ==== Page.getPagePath() ==== If you want to know the file path to a wiki page, use the method {{{Page.getPagePath()}}}. {{{#!python pagename = u'StartPage' print Page(request, pagename).getPagePath() }}} output: {{{ /home/workspace/moin-1.9/wiki/underlay/pages/StartPage }}} <> ==== Page.get_raw_body() ==== To read the source of a page use {{{Page.get_raw_body()}}}. {{{#!python pagename = u'StartPage' text = Page(request, pagename).get_raw_body() print text }}} Output {{{ ## Please edit system and help pages ONLY in the master wiki! ## For more information, please see MoinMoin:MoinDev/Translation. ##master-page:FrontPage ##master-date:2007-17-12 21:30:15 #format wiki #language de #pragma section-numbers off = WikiName Wiki = ... ... }}} ==== Page.send_page() ==== Using {{{Page.send_page()}}} send the formatted page to the output device (usually the browser). Optionally, you can print a message on the {{{msg}}} parameter. This message is then displayed in a box above the page. If this method is not used for a browser, an {{{http_header}}} should not be sent. {{{#!python pagename = u'StartPage' Page(request, pagename).send_page(emit_headers=False) }}} The output in the console starts with: {{{ StartPage - MoinMoin DesktopEdition }}} === auth === To authenticate to the wiki, use {{{ user = MoinMoin.auth.handle_login(request, username='foo', password='bar' request.user = user }}} handle_login returns a user, which has to be set in the request to actually have a request for that user. This is required e.g. for write access to pages when that needs authentication === search === Since moin-1.9 xapian the indexed search using regular expressions is available. Prior to 1.9 the slow search method moin search was used. And this is still the default. To search with xapian, you must use a version> = 1.0.6 and configure wikiconfig like this: /* HelpOnXapian */ {{{ xapian_search = True xapian_stemming = True }}} If the wiki has pages or even attachments, an index should be formed. {{{ moin --config-dir=/where/your/configdir/is --wiki-url=wiki-url/ index build --mode=add }}} The xapian is an index of words in the wiki pages. Using filters text data from attachments can also be extracted making the attachments also searchable. Unlike the default search, but only words can be found which are also included in the index. The Stemming it allows that stems are found. Words can be found part of a regex with security assistance. /* BAD_TRANSLATION */ ==== search pages ==== The following section describes how pages of hand a category assignment can be found. {{{#!python from MoinMoin.search import searchPages }}} A small example about how you can look for pages belonging to the category CategoryHomePage: {{{#!python from MoinMoin.web.contexts import ScriptContext request = ScriptContext() from MoinMoin.Page import Page from MoinMoin import search needle = "category:CategoryHomePage" search_result = search.searchPages(request, needle) for title in search_result.hits: print title.page_name }}} === page editor === The class {{{PageEditor}}} is used for all write operations to a wiki page. For operations that are made to wiki pages or any attachments, the user's access rights are checked. (see HelpOnAccessControlLists) {{{#!python from MoinMoin.PageEditor import PageEditor }}} ==== PageEditor.saveText() ==== {{{PageEditor.saveText()}}} is used to save text on a page. In addition to the text you want to save, you must also specify the revision of the page as a parameter. {{{#!python pagename = u'TestPage' text = u'This is an example' print PageEditor(request, pagename).saveText(text, 0) }}} The result of a successful save is: {{{ 'Thank you for your changes. Your attention to detail is appreciated.' }}} This page is now in the Wiki, as you can easily check with a web browser. ''http://localhost:8080/TestPage'' If you repeat the call {{{PageEditor(request, pagename).saveText(text, 0)}}} without a change to the {{{text}}} it will be denied and you'll get an error message triggered by an exception. {{{ MoinMoin.PageEditor.Unchanged: You did not change the page content, not saved! }}} This error message should always be caught with a {{{try ... except:}}} block, see the following example: {{{#!python pagename = u'TestPage' page = PageEditor(request, pagename) text = u'This is an example' try: page.saveText(text, 0) except page.Unchanged: print "You did not change the page content, not saved!" }}} <> ==== PageEditor.deletePage() ==== The method {{{PageEditor.deletePage}}} is used to delete a page. If a page is deleted, a new revision is created without any data - the old versions of the page remain however so they can be recovered. {{{#!python pagename = u'TestPage' print PageEditor(request, pagename).deletePage() }}} The confirmation of the successful deletion is: {{{ (True, u'Page "TestPage" was successfully deleted!') }}} === AttachFile === The module {{{AttachFile}}} contains the functions needed to store attachments to wiki pages (see HelpOnActions / AttachFile) or to load attachments. The plan for future versions of MoinMoin is that attachments become like wiki pages (and thus also be versionable). This will then be accounted by this class. {{{#!python from MoinMoin.action import AttachFile }}} ==== AttachFile.exists() ==== The method {{{AttachFile.exists()}}} determines whether a particular attachment already exists. {{{#!python pagename = u'WikiSandkasten' attachment = u'dateianhang.png' print AttachFile.exists(request, pagename, attachment) }}} output: {{{ True }}} ==== AttachFile.getAttachDir() ==== The method {{{AttachFile.getAttachDir()}}} returns the path of the attachment. {{{#!python pagename = u'WikiSandkasten' attachment = u'dateianhang.png' print AttachFile.getAttachDir(request, pagename) }}} output: {{{ /home/workspace/moin-1.9/wiki/underlay/pages/WikiSandkasten/attachments }}} ==== AttachFile.getAttachUrl() ==== The method {{{AttachFile.getAttachUrl()}}} returns a URL for the attachment. {{{#!python pagename = u'WikiSandkasten' attachment = u'dateianhang.png' print AttachFile.getAttachUrl(pagename, attachment, request) }}} output: {{{ ./WikiSandkasten?action=AttachFile&do=get&target=dateianhang.png }}} === logfile === MoinMoin has two logging systems: {{{eventlog}}} is mainly for events like which browser is used or what pages were viewed in one day, recorded for statistical analysis. {{{editlog}}} stores events like when a page gets created, edited, or deleted, and this information will be displayed by clicking 'Info' on a page. <> ==== logfile.eventlog ==== The class {{{eventlog}}} managing access to wiki pages. You have the option to choose between two filters. {{{'VIEWPAGE'}}} about the pages that are viewed and {{{'SAVEPAGE'}}} about those that are saved. The following example counts the hits on ''StartPage''. Before the page views are counted, it is checked whether the user has read access on the page. If this is not the case, the value {{{0}}} is issued. {{{#!python from MoinMoin.logfile import eventlog event_type = u'VIEWPAGE' pagename = u'LanguageSetup' event_log = eventlog.EventLog(request) count = 0 if request.user.may.read(pagename): test = filter(lambda line: line[1] in event_type and line[2]['pagename'] == pagename, event_log) count = len(test) print count }}} output: {{{ 8 }}} ==== logfile.editlog ==== Using the Class {{{logfile.editlog}}} we can check the editing history of page. Wiki pages can be created, renamed and deleted. This is noted in {{{editlog}}}. {{{u'SAVENEW'}}} is for newly created pages, {{{u'SAVE/RENAME'}}} is for pages that have been renamed, {{{u'SAVE'}}} is for deleted pages (see [[#PageEditordeletepage|PageEditor.deletePage]]). The following example shows the newly created Wiki pages in your wiki, and creation date of the pages. Due to the condition {{{line.action == 'SAVENEW'}}} only pages that have been recreated in your wiki will be printed. {{{#!python from MoinMoin import wikiutil from MoinMoin.logfile import editlog edit_log = editlog.EditLog(request) for line in edit_log.reverse(): if (request.user.may.read(line.pagename) and line.action == 'SAVENEW'): timestamp = request.user.getTime(wikiutil.version2timestamp(line.ed_time_usecs)) year, month, day = timestamp[0:3] print "%s %s.%s.%s" % (line.pagename, day, month, year) }}} Sample output: {{{ ExamplePage1 8.9.2009 ExamplePage2 8.9.2009 ExamplePage3 9.9.2009 }}} === wikiutil === The class {{{wikiutil}}} contains various utility functions. {{{#!python from MoinMoin import wikiutil }}} ==== wikiutil.escape() ==== The method {{{wikiutil.escape()}}} To mask any HTML special characters. Anything that contains HTML special characters must be escaped before output. This method applies also to the formatter (see page [[#formatter|formatter]] ). {{{#!python print wikiutil.escape(u'') }}} output: {{{ <html> }}} <> ==== wikiutil.createTicket() ==== By applying the method {{{wikiutil.createTicket()}}} create a ticket that you can use for verification of forms. This allows you to check whether the incoming form data come from a form you created (see [[#ticket|Example]]). {{{#!python print wikiutil.createTicket(request) }}} output: {{{ 0046e8506e.None.show.8ea03fb9d6e50bf60721aa }}} ==== wikiutil.checkTicket() ==== The method {{{wikiutil.checkTicket()}}} checks whether the ticket is known to the system (see [[#ticket|Example]] ). {{{#!python print wikiutil.checkTicket(request, '0046e8506e.None.show.8ea03fb9d6e50bf60721aa') }}} output: {{{ True }}} <> ==== wikiutil.invoke_extension_function() ==== The application of the method {{{wikiutil.invoke_extension_function()}}} allows you to comfortably evaluate parameters of your macros (see [[#pluginmacro|Plugins macro]] ). You can define a default value for the parameter. You can specify a list of allowed input entries. On different inputs an error message is produced. ==== wikiutil.version2timestamp() ==== The method {{{wikiutil.version2timestamp()}}} convertes the time information that is used in MoinMoin to the UNIX time format. ==== wikiutil.timestamp2version() ==== The method {{{wikiutil.timestamp2version()}}} is the UNIX time information into the equivalent of time spent in MoinMoin. /* BAD_TRANSLATION */ ==== wikiutil.renderText() ==== With the method {{{wikiutil.renderText()}}} wiki text will be parsed and displayed in HTML. {{{#!python from MoinMoin import wikiutil from MoinMoin.Page import Page from MoinMoin.web.contexts import ScriptContext request = ScriptContext() pagename = u'NeverExistingPage' request.formatter.page = Page(request, pagename) from MoinMoin.parser.text_moin_wiki import Parser as WikiParser text = "WikiName" wikiutil.renderText(request, WikiParser, text) }}} output: {{{ u'WikiName ' }}} === user === A set of useful functions for the {{{User}}} Object classes. The class {{{User}}} represents a user and provides access to his profile. {{{#!python from MoinMoin import user }}} ==== user.User(request, auth_method="new-user") ==== The following example creates a user named "ExampleUser". {{{#!python import os from MoinMoin.web.contexts import ScriptContext request = ScriptContext() from MoinMoin import user, wikiutil the_user = user.User(request, auth_method="new-user") the_user.name = "ExampleUser" the_user.email = "ExampleUser@localhost" the_user.enc_password = user.encodePassword("zoo0Eifi") if (user.isValidName(request, the_user.name) and not user.getUserId(request, the_user.name) and not user.get_by_email_address(request, the_user.email)): print "This user with the userid %s doesn't exist yet." % the_user.id the_user.save() filename = os.path.join(request.cfg.user_dir, the_user.id) if os.path.exists(filename): print "The user file %s was created" % filename else: print "user credential already used - nothing done" }}} output: {{{ This user with the userid 1257617552.0.33542 doesn't exist yet. The user file /home/workspace/moin-1.9/wiki/data/user/1257617552.0.33542 was created }}} ==== user.getUserList() ==== To get all numeric uids of users use {{{user.getUserList}}}. {{{#!python uids = user.getUserList(request) print uids }}} output: {{{ ['1252446015.52.43538', '1252448264.85.4326', '1257617552.0.33542'] }}} ==== user.getUserId() ==== Use this method to convert user names to user uids. The uid of the user name is required if you want to access a user. {{{#!python uid = user.getUserId(request, u'ExampleUser') print uid }}} output: {{{ 1257617552.0.33542 }}} ==== user.User.name ==== the username is stored in the variable {{{user.User.name}}}. So if a user with the name ''!ExampleUser'' you'll get this output: {{{#!python uid = user.getUserId(request, u'ExampleUser') user_object = user.User(request, uid) print user_object.name }}} output: {{{ ExampleUser }}} ==== user.User.exists() ==== The method {{{user.User.exists()}}} is used to determine whether a user exists. {{{#!python uid = user.getUserId(request, u'ExampleUser') print user.User(request, uid).exists() }}} output: {{{ True }}} ==== user.User.isSuperUser() ==== The method {{{user.User.isSuperUser()}}} Checks whether the user is a superuser. Super users have some special rights. (see HelpOnSuperUser) {{{#!python uid = user.getUserId(request, u'ExampleUser') print user.User(request, uid).isSuperUser() }}} output: {{{ False }}} ==== user.User.save() ==== With the method {{{user.User.save()}}} the user profile is saved. {{{#!python uid = user.getUserId(request, u'ExampleUser') this_user = user.User(request, uid) if this_user.exists(): this_user.save() }}} ==== user.User.getSubscriptionList() ==== The method {{{user.User.getSubscriptionList()}}} returns the pages a user has subscribed to. {{{#!python uid = user.getUserId(request, u'ExampleUser') print user.User(request, uid).getSubscriptionList() }}} output: {{{ [] }}} ==== user.User.subscribe() ==== The method {{{user.User.subscribe()}}} is used to subscribe to a page. With a return value of {{{True}}} the successful subscription to a page is confirmed. {{{#!python uid = user.getUserId(request, u'ExampleUser') this_user = user.User(request, uid) pagename = u'StartPage' print this_user.subscribe(pagename) }}} output: {{{ True }}} ==== user.User.unsubscribe() ==== The method {{{user.User.unsubscribe()}}} is used to un-subscripe from of a page. {{{#!python uid = user.getUserId(request, u'ExampleUser') this_user = user.User(request, uid) pagename = u'StartPage' print this_user.unsubscribe(pagename) }}} output: {{{ True }}} ==== user.User.getTime() ==== The method {{{user.User.getTime()}}} is used to convert the time in the time zone of the user. If you specify the value {{{0}}}, the current time is used. {{{#!python uid = user.getUserId(request, u'ExampleUser') this_user = user.User(request, uid) print this_user.getTime(0) }}} output: {{{ time.struct_time(tm_year=2009, tm_mon=11, tm_mday=7, tm_hour=18, tm_min=21, tm_sec=56, tm_wday=5, tm_yday=311, tm_isdst=0) }}} <> === formatter === A Formatter is responsible for output generation. For the HTML output formatter is an instance of {{{formatter.text_html}}} included {{{request}}} object. {{{{#!wiki comment If you send everything you spend, by the {{{formatter}}}, ensuring that no user of your program is able to inject any HTML or Javascript commands in your application. If this is possible for a user, this is called cross-site scripting (XSS). Through the use of XSS can someone steal your user data. By entering