This patch:

1. Changes Param.label, Param.doc so they can be either text.Gettext or
str instances.  This is transitional till we get any outstanding patches
merged in, then they will only allow text.Gettext instances.

2. Adds a docstring to the ipalib/parameters.py module explaining the
difference between cli_name, label, and doc.  It also has some style
guidelines for the label and doc.

3. Marks all Param.label and Param.doc for translation, does some
cleanup to hopefully make things a bit more consistent.

4. Various small changes needed to adjust to Param.label, Param.doc
being text.Gettext instances.
>From c3cfcd0f73d6078146b2785c4f0f35692883fec6 Mon Sep 17 00:00:00 2001
From: Jason Gerard DeRose <jder...@redhat.com>
Date: Fri, 19 Feb 2010 09:08:16 -0700
Subject: [PATCH] Translatable Param.label, Param.doc

---
 ipalib/frontend.py                   |    2 +-
 ipalib/parameters.py                 |   91 ++++++++++++++++++++++++++++++----
 ipalib/plugins/aci.py                |   31 +++++++----
 ipalib/plugins/automount.py          |   23 +++++----
 ipalib/plugins/baseldap.py           |   42 +++++++---------
 ipalib/plugins/cert.py               |   50 ++++++++++---------
 ipalib/plugins/config.py             |   41 +++++++--------
 ipalib/plugins/dns.py                |   79 ++++++++++++++----------------
 ipalib/plugins/group.py              |   22 ++++----
 ipalib/plugins/hbac.py               |   25 ++++++----
 ipalib/plugins/host.py               |   40 ++++++++-------
 ipalib/plugins/hostgroup.py          |   14 +++---
 ipalib/plugins/krbtpolicy.py         |   11 +++--
 ipalib/plugins/migration.py          |   17 ++++---
 ipalib/plugins/netgroup.py           |   14 ++---
 ipalib/plugins/passwd.py             |    4 +-
 ipalib/plugins/pwpolicy.py           |   43 +++++++++-------
 ipalib/plugins/rolegroup.py          |   13 ++---
 ipalib/plugins/service.py            |    8 ++--
 ipalib/plugins/taskgroup.py          |   13 ++---
 ipalib/plugins/user.py               |   28 +++++-----
 ipalib/text.py                       |   23 ++++-----
 tests/test_ipalib/test_parameters.py |    6 +-
 23 files changed, 363 insertions(+), 277 deletions(-)

diff --git a/ipalib/frontend.py b/ipalib/frontend.py
index 6ed388f..4d0df3a 100644
--- a/ipalib/frontend.py
+++ b/ipalib/frontend.py
@@ -844,7 +844,7 @@ class Command(HasParam):
         if options.get('raw', False):
             labels = None
         else:
-            labels = dict((p.name, p.label) for p in self.output_params())
+            labels = dict((p.name, unicode(p.label)) for p in self.output_params())
 
         for o in self.output:
             if 'no_display' in self.output[o].flags:
diff --git a/ipalib/parameters.py b/ipalib/parameters.py
index 3911d6e..8c6a7e7 100644
--- a/ipalib/parameters.py
+++ b/ipalib/parameters.py
@@ -20,13 +20,83 @@
 """
 Parameter system for command plugins.
 
-TODO:
-
-  * Change rule call signature to rule(_, value, **kw) so that rules can also
-    validate relative to other parameter values (e.g., login name as it relates
-    to first name and last name)
-
-  * Add the _rule_pattern() methods to `Bytes` and `Str`
+A `Param` instance can be used to describe an argument or option that a command
+takes, or an attribute that a command returns.  The `Param` base class is not
+used directly, but there are many subclasses for specific Python data types
+(like `Str` or `Int`) and specific properties (like `Password`).
+
+To create a `Param` instance, you must always provide the parameter *name*,
+which should be the LDAP attribute name if the parameter describes the attribute
+of an LDAP entry.  For example, we could create an `Str` instance describing the user's last-name attribute like this:
+
+>>> from ipalib import Str
+>>> sn = Str('sn')
+>>> sn.name
+'sn'
+
+When creating a `Param`, there are also a number of optional kwargs which
+which can provide additional meta-data and functionality.  For example, every
+parameter has a *cli_name*, the name used on the command-line-interface.  By
+default the *cli_name* is the same as the *name*:
+
+>>> sn.cli_name
+'sn'
+
+But often the LDAP attribute name isn't user friendly for the command-line, so
+you can override this with the *cli_name* kwarg:
+
+>>> sn = Str('sn', cli_name='last')
+>>> sn.name
+'sn'
+>>> sn.cli_name
+'last'
+
+Note that the RPC interfaces (and the internal processing pipeline) always use
+the parameter *name*, regardless of what the *cli_name* might be.
+
+A `Param` also has two translatable kwargs: *label* and *doc*.  These must both
+be `Gettext` instances.  They both default to a place-holder `FixMe` instance,
+a subclass of `Gettext` used to mark a missing translatable string:
+
+>>> sn.label
+FixMe('sn')
+>>> sn.doc
+FixMe('sn')
+
+The *label* is a short phrase describing the parameter.  It's used on the CLI
+when interactively prompting for values, and as a label for form inputs in the
+web-UI.  The *label* should start with an initial capital.  For example:
+
+>>> from ipalib import _
+>>> sn = Str('sn',
+...     cli_name='last',
+...     label=_('Last name'),
+... )
+>>> sn.label
+Gettext('Last name')
+
+The *doc* is a longer description of the parameter.  It's used on the CLI when
+displaying the help information for a command, and as extra instruction for a
+form input on the web-UI.  By default the *doc* is the same as the *label*:
+
+>>> sn.doc
+Gettext('Last name')
+
+But you can override this with the *doc* kwarg.  Like the *label*, the *doc*
+should also start with an initial capital and should not end with any
+punctuation.  For example:
+
+>>> sn = Str('sn',
+...     cli_name='last',
+...     label=_('Last name'),
+...     doc=_("The user's last name"),
+... )
+>>> sn.doc
+Gettext("The user's last name")
+
+Demonstration aside, you should always provide at least the *label* so the
+various UIs are translatable.  Only provide the *doc* if the parameter needs
+a more detailed description for clarity.
 """
 
 import re
@@ -37,6 +107,7 @@ from plugable import ReadOnly, lock, check_name
 from errors import ConversionError, RequirementError, ValidationError
 from errors import PasswordMismatch
 from constants import NULLS, TYPE_ERROR, CALLABLE_ERROR
+from text import Gettext, FixMe
 import csv
 
 
@@ -229,8 +300,8 @@ class Param(ReadOnly):
     kwargs = (
         ('cli_name', str, None),
         ('cli_short_name', str, None),
-        ('label', str, None),
-        ('doc', str, None),
+        ('label', (str, Gettext), None),
+        ('doc', (str, Gettext), None),
         ('required', bool, True),
         ('multivalue', bool, False),
         ('primary_key', bool, False),
@@ -286,7 +357,7 @@ class Param(ReadOnly):
             kw['cli_name'] = self.name
 
         if kw.get('label') is None:
-            kw['label'] = '<%s>' % self.name
+            kw['label'] = FixMe(self.name)
 
         if kw.get('doc') is None:
             kw['doc'] = kw['label']
diff --git a/ipalib/plugins/aci.py b/ipalib/plugins/aci.py
index a722d76..4914efe 100644
--- a/ipalib/plugins/aci.py
+++ b/ipalib/plugins/aci.py
@@ -203,47 +203,56 @@ class aci(Object):
     takes_params = (
         Str('aciname',
             cli_name='name',
-            doc='name',
+            label=_('ACI name'),
             primary_key=True,
         ),
         Str('taskgroup?',
             cli_name='taskgroup',
-            doc='taskgroup ACI grants access to',
+            label=_('Taskgroup'),
+            doc=_('Taskgroup ACI grants access to'),
         ),
         Str('group?',
             cli_name='group',
-            doc='user group ACI grants access to',
+            label=_('User group'),
+            doc=_('User group ACI grants access to'),
         ),
         List('permissions',
             cli_name='permissions',
-            doc='comma-separated list of permissions to grant' \
-                '(read, write, add, delete, selfwrite, all)',
+            label=_('Permissions'),
+            doc=_('comma-separated list of permissions to grant' \
+                '(read, write, add, delete, selfwrite, all)'),
             normalizer=_normalize_permissions,
         ),
         List('attrs?',
             cli_name='attrs',
-            doc='comma-separated list of attributes',
+            label=_('Attributes'),
+            doc=_('Comma-separated list of attributes'),
         ),
         StrEnum('type?',
             cli_name='type',
-            doc='type of IPA object (user, group, host)',
+            label=_('Type'),
+            doc=_('type of IPA object (user, group, host)'),
             values=(u'user', u'group', u'host'),
         ),
         Str('memberof?',
             cli_name='memberof',
-            doc='member of a group',
+            label=_('Member of'),  # FIXME: Does this label make sense?
+            doc=_('Member of a group'),
         ),
         Str('filter?',
             cli_name='filter',
-            doc='legal LDAP filter (e.g. ou=Engineering)',
+            label=_('Filter'),
+            doc=_('Legal LDAP filter (e.g. ou=Engineering)'),
         ),
         Str('subtree?',
             cli_name='subtree',
-            doc='subtree to apply ACI to',
+            label=_('Subtree'),
+            doc=_('Subtree to apply ACI to'),
         ),
         Str('targetgroup?',
             cli_name='targetgroup',
-            doc='group to apply ACI to',
+            label=_('Target group'),
+            doc=_('Group to apply ACI to'),
         ),
     )
 
diff --git a/ipalib/plugins/automount.py b/ipalib/plugins/automount.py
index c56c7da..71a2182 100644
--- a/ipalib/plugins/automount.py
+++ b/ipalib/plugins/automount.py
@@ -107,8 +107,8 @@ class automountlocation(LDAPObject):
     takes_params = (
         Str('cn',
             cli_name='location',
-            label='Location',
-            doc='automount location name',
+            label=_('Location'),
+            doc=_('Automount location name'),
             primary_key=True,
         ),
     )
@@ -227,14 +227,13 @@ class automountmap(LDAPObject):
     takes_params = (
         Str('automountmapname',
             cli_name='map',
-            label='Map',
+            label=_('Map'),
+            doc=_('Aautomount map name'),
             primary_key=True,
-            doc='automount map name',
         ),
         Str('description?',
             cli_name='desc',
-            label='Description',
-            doc='description',
+            label=_('Description'),
         ),
     )
 
@@ -315,16 +314,17 @@ class automountkey(LDAPObject):
     takes_params = (
         Str('automountkey',
             cli_name='key',
-            doc='key name',
+            label=_('Key'),
+            doc=_('Automount key name'),
             primary_key=True,
         ),
         Str('automountinformation',
             cli_name='info',
-            doc='mount information',
+            label=_('Mount information'),
         ),
         Str('description?',
             cli_name='desc',
-            doc='description',
+            label=_('description'),
         ),
     )
 
@@ -348,11 +348,12 @@ class automountmap_add_indirect(LDAPCreate):
     takes_options = LDAPCreate.takes_options + (
         Str('key',
             cli_name='mount',
-            doc='mount point',
+            label=_('Mount point'),
         ),
         Str('parentmap?',
             cli_name='parentmap',
-            doc='name of parent automount map (default: auto.master)',
+            label=_('Parent map'),
+            doc=_('Name of parent automount map (default: auto.master)'),
             default=u'auto.master',
             autofill=True,
         ),
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 9aa002a..e03ac2e 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -28,6 +28,7 @@ from ipalib import Flag, List, Str
 from ipalib.base import NameSpace
 from ipalib.cli import to_cli, from_cli
 from ipalib import output
+from ipalib.text import _
 
 
 def validate_add_attribute(ugettext, attr):
@@ -129,23 +130,27 @@ class LDAPObject(Object):
             )
 
 
+# Options used by create and update.
+_attr_options = (
+    Str('addattr*', validate_add_attribute,
+        cli_name='addattr',
+        doc=_('Add an attribute/value pair. Format is attr=value'),
+        exclude='webui',
+    ),
+    Str('setattr*', validate_set_attribute,
+        cli_name='setattr',
+        doc=_('Set an attribute to an name/value pair. Format is attr=value'),
+        exclude='webui',
+    ),
+)
+
+
 class LDAPCreate(crud.Create):
     """
     Create a new entry in LDAP.
     """
 
-    takes_options = (
-        Str('addattr*', validate_add_attribute,
-            cli_name='addattr',
-            doc='Add an attribute/value pair. Format is attr=value',
-            exclude='webui',
-        ),
-        Str('setattr*', validate_set_attribute,
-            cli_name='setattr',
-            doc='Set an attribute to an name/value pair. Format is attr=value',
-            exclude='webui',
-        ),
-    )
+    takes_options = _attr_options
 
     def get_args(self):
         for key in self.obj.get_ancestor_primary_keys():
@@ -272,18 +277,7 @@ class LDAPUpdate(LDAPQuery, crud.Update):
     Update an LDAP entry.
     """
 
-    takes_options = (
-        Str('addattr*', validate_add_attribute,
-            cli_name='addattr',
-            doc='Add an attribute/value pair. Format is attr=value',
-            exclude='webui',
-        ),
-        Str('setattr*', validate_set_attribute,
-            cli_name='setattr',
-            doc='Set an attribute to an name/value pair. Format is attr=value',
-            exclude='webui',
-        ),
-    )
+    takes_options = _attr_options
 
     def execute(self, *keys, **options):
         ldap = self.obj.backend
diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py
index 3931d21..426e6d5 100644
--- a/ipalib/plugins/cert.py
+++ b/ipalib/plugins/cert.py
@@ -34,11 +34,10 @@ from ipalib import x509
 from ipalib.plugins.virtual import *
 from ipalib.plugins.service import split_principal
 import base64
-from ipalib.request import context
 from pyasn1.error import PyAsn1Error
 import logging
 import traceback
-from ipalib.request import ugettext as _
+from ipalib.text import _
 from ipalib.request import context
 from ipalib.output import Output
 
@@ -173,27 +172,28 @@ class cert_request(VirtualCommand):
 
     takes_options = (
         Str('principal',
-            doc="service principal for this certificate (e.g. HTTP/test.example.com)",
+            label=_('Principal'),
+            doc=_('Service principal for this certificate (e.g. HTTP/test.example.com)'),
         ),
         Str('request_type',
             default=u'pkcs10',
             autofill=True,
         ),
         Flag('add',
-            doc="automatically add the principal if it doesn't exist",
+            doc=_("automatically add the principal if it doesn't exist"),
             default=False,
             autofill=True
         ),
         Str('certificate?',
-            label='Certificate',
+            label=_('Certificate'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('subject?',
-            label='Subject',
+            label=_('Subject'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('serial_number?',
-            label='Serial number',
+            label=_('Serial number'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
@@ -324,13 +324,13 @@ class cert_status(VirtualCommand):
 
     takes_args = (
         Str('request_id',
-            label='Request id',
+            label=_('Request id'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
     takes_options = (
         Str('cert_request_status?',
-            label='Request status',
+            label=_('Request status'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
@@ -346,21 +346,25 @@ class cert_status(VirtualCommand):
 api.register(cert_status)
 
 
+_serial_number = Str('serial_number',
+    label=_('Serial number'),
+    doc=_('Serial number in decimal or if prefixed with 0x in hexadecimal'),
+)
+
 class cert_get(VirtualCommand):
     """
     Retrieve an existing certificate.
     """
 
-    takes_args = (Str('serial_number',
-                      label='Serial number',
-                      doc='serial number in decimal or if prefixed with 0x in hexadecimal'))
+    takes_args = _serial_number
+
     takes_options = (
         Str('certificate?',
-            label='Certificate',
+            label=_('Certificate'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('subject?',
-            label='Subject',
+            label=_('Subject'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
@@ -381,11 +385,11 @@ class cert_revoke(VirtualCommand):
     Revoke a certificate.
     """
 
-    takes_args = (Str('serial_number',
-                      doc='serial number in decimal or if prefixed with 0x in hexadecimal'))
+    takes_args = _serial_number
+
     takes_options = (
         Flag('revoked?',
-            label='Revoked',
+            label=_('Revoked'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
@@ -394,14 +398,14 @@ class cert_revoke(VirtualCommand):
     # FIXME: The default is 0.  Is this really an Int param?
     takes_options = (
         Int('revocation_reason?',
-            doc='Reason for revoking the certificate (0-10)',
+            label=_('Reason'),
+            doc=_('Reason for revoking the certificate (0-10)'),
             minvalue=0,
             maxvalue=10,
             default=0,
         ),
     )
 
-
     def execute(self, serial_number, **kw):
         self.check_access()
         return dict(
@@ -416,15 +420,15 @@ class cert_remove_hold(VirtualCommand):
     Take a revoked certificate off hold.
     """
 
-    takes_args = (Str('serial_number',
-                      doc='serial number in decimal or if prefixed with 0x in hexadecimal'))
+    takes_args = _serial_number
+
     takes_options = (
         Flag('unrevoked?',
-            label='Unrevoked',
+            label=_('Unrevoked'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('error_string?',
-            label='Error',
+            label=_('Error'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
diff --git a/ipalib/plugins/config.py b/ipalib/plugins/config.py
index 722de73..b49dba8 100644
--- a/ipalib/plugins/config.py
+++ b/ipalib/plugins/config.py
@@ -24,6 +24,7 @@ IPA configuration
 from ipalib import api
 from ipalib import Bool, Int, Str
 from ipalib.plugins.baseldap import *
+from ipalib import _
 
 
 class config(LDAPObject):
@@ -54,46 +55,45 @@ class config(LDAPObject):
     takes_params = (
         Int('ipamaxusernamelength?',
             cli_name='maxusername',
-            label='Max. Username length',
-            doc='Max. Username length',
+            label=_('Max username length'),
             minvalue=1,
         ),
         Str('ipahomesrootdir?',
             cli_name='homedirectory',
-            label='Home Directory base',
-            doc='Default location of home directories',
+            label=_('Home directory base'),
+            doc=_('Default location of home directories'),
         ),
         Str('ipadefaultloginshell?',
             cli_name='defaultshell',
-            label='Default shell',
-            doc='Default shell for new users',
+            label=_('Default shell'),
+            doc=_('Default shell for new users'),
         ),
         Str('ipadefaultprimarygroup?',
             cli_name='defaultgroup',
-            label='Default users group',
-            doc='Default group for new users',
+            label=_('Default users group'),
+            doc=_('Default group for new users'),
         ),
         Str('ipadefaultemaildomain?',
             cli_name='emaildomain',
-            label='Default e-mail domain',
-            doc='Default e-mail domain new users',
+            label=_('Default e-mail domain'),
+            doc=_('Default e-mail domain new users'),
         ),
         Int('ipasearchtimelimit?',
             cli_name='searchtimelimit',
-            label='Search time limit',
-            doc='Max. amount of time (sec.) for a search (-1 is unlimited)',
+            label=_('Search time limit'),
+            doc=_('Max. amount of time (sec.) for a search (-1 is unlimited)'),
             minvalue=-1,
         ),
         Int('ipasearchrecordslimit?',
             cli_name='searchrecordslimit',
-            label='Search size limit',
-            doc='Max. number of records to search (-1 is unlimited)',
+            label=_('Search size limit'),
+            doc=_('Max. number of records to search (-1 is unlimited)'),
             minvalue=-1,
         ),
         Str('ipausersearchfields?',
             cli_name='usersearch',
-            label='User search fields',
-            doc='A comma-separated list of fields to search when searching for users',
+            label=_('User search fields'),
+            doc=_('A comma-separated list of fields to search when searching for users'),
         ),
         Str('ipagroupsearchfields?',
             cli_name='groupsearch',
@@ -101,14 +101,14 @@ class config(LDAPObject):
             doc='A comma-separated list of fields to search when searching for groups',
         ),
         Bool('ipamigrationenabled?',
-            label='Migration mode',
             cli_name='enable_migration',
-            doc='Enabled migration mode',
+            label=_('Migration mode'),
+            doc=_('Enabled migration mode'),
         ),
         Str('ipacertificatesubjectbase?',
-            label='Certificate Subject base',
             cli_name='subject',
-            doc='base for certificate subjects (OU=Test,O=Example)',
+            label=_('Certificate Subject base'),
+            doc=_('base for certificate subjects (OU=Test,O=Example)'),
         ),
     )
 
@@ -139,4 +139,3 @@ class config_show(LDAPRetrieve):
     """
 
 api.register(config_show)
-
diff --git a/ipalib/plugins/dns.py b/ipalib/plugins/dns.py
index 397eb0b..5f6949a 100644
--- a/ipalib/plugins/dns.py
+++ b/ipalib/plugins/dns.py
@@ -115,56 +115,57 @@ class dns(Object):
     takes_params = (
         Str('idnsname',
             cli_name='name',
-            doc='zone name (FQDN)',
+            label=_('Zone'),
+            doc=_('Zone name (FQDN)'),
             normalizer=lambda value: value.lower(),
             primary_key=True,
         ),
         Str('idnssoamname',
             cli_name='name_server',
-            doc='authoritative name server',
+            label=_('Authoritative name server'),
         ),
         Str('idnssoarname',
             cli_name='admin_email',
-            doc='administrator e-mail address',
+            label=_('administrator e-mail address'),
             default_from=lambda idnsname: 'root.%s' % idnsname,
             normalizer=lambda value: value.replace('@', '.'),
         ),
         Int('idnssoaserial?',
             cli_name='serial',
-            doc='SOA serial',
+            label=_('SOA serial'),
         ),
         Int('idnssoarefresh?',
             cli_name='refresh',
-            doc='SOA refresh',
+            label=_('SOA refresh'),
         ),
         Int('idnssoaretry?',
             cli_name='retry',
-            doc='SOA retry',
+            label=_('SOA retry'),
         ),
         Int('idnssoaexpire?',
             cli_name='expire',
-            doc='SOA expire',
+            label=_('SOA expire'),
         ),
         Int('idnssoaminimum?',
             cli_name='minimum',
-            doc='SOA minimum',
+            label=_('SOA minimum'),
         ),
         Int('dnsttl?',
             cli_name='ttl',
-            doc='SOA time to live',
+            label=_('SOA time to live'),
         ),
         StrEnum('dnsclass?',
             cli_name='class',
-            doc='SOA class',
+            label=_('SOA class'),
             values=_record_classes,
         ),
         Flag('idnsallowdynupdate',
             cli_name='allow_dynupdate',
-            doc='allow dynamic update?',
+            label=_('allow dynamic update?'),
         ),
         Str('idnsupdatepolicy?',
             cli_name='update_policy',
-            doc='BIND update policy',
+            label=_('BIND update policy'),
         ),
     )
 
@@ -389,7 +390,7 @@ class dns_enable(Command):
     takes_args = (
         Str('zone',
             cli_name='zone',
-            doc='zone name',
+            label=_('Zone name'),
             normalizer=lambda value: value.lower(),
         ),
     )
@@ -423,8 +424,7 @@ class dns_disable(Command):
     """
     takes_args = (
         Str('zone',
-            cli_name='zone',
-            doc='zone name',
+            label=_('Zone name'),
             normalizer=lambda value: value.lower(),
         ),
     )
@@ -456,38 +456,37 @@ class dns_add_rr(Command):
     """
     Add new DNS resource record.
     """
+
     takes_args = (
         Str('zone',
-            cli_name='zone',
-            doc='zone name',
+            label=_('Zone name'),
             normalizer=lambda value: value.lower(),
         ),
         Str('idnsname',
             cli_name='resource',
-            doc='resource name',
+            label=_('resource name'),
             default_from=lambda zone: zone.lower(),
             attribute=True,
         ),
         StrEnum('type',
-            cli_name='type',
-            doc='record type',
+            label=_('Record type'),
             values=_record_types,
         ),
         Str('data',
-            cli_name='data',
-            doc='type-specific data',
+            label=_('Data'),
+            doc=_('Type-specific data'),
         ),
     )
 
     takes_options = (
         Int('dnsttl?',
             cli_name='ttl',
-            doc='time to live',
+            label=_('Time to live'),
             attribute=True,
         ),
         StrEnum('dnsclass?',
             cli_name='class',
-            doc='class',
+            label=_('Class'),
             values=_record_classes,
             attribute=True,
         ),
@@ -572,26 +571,25 @@ class dns_del_rr(Command):
     """
     Delete DNS resource record.
     """
+
     takes_args = (
         Str('zone',
-            cli_name='zone',
-            doc='zone name',
+            label=_('Zone name'),
             normalizer=lambda value: value.lower(),
         ),
         Str('idnsname',
             cli_name='resource',
-            doc='resource name',
+            label=_('Resource name'),
             default_from=lambda zone: zone.lower(),
             attribute=True,
         ),
         StrEnum('type',
-            cli_name='type',
-            doc='record type',
+            label=_('Record type'),
             values=_record_types,
         ),
         Str('data',
-            cli_name='data',
-            doc='type-specific data',
+            label=_('Data'),
+            doc=_('Type-specific data'),
         ),
     )
 
@@ -661,30 +659,27 @@ class dns_find_rr(Command):
     """
     takes_args = (
         Str('zone',
-            cli_name='zone',
-            doc='zone name',
+            label=_('Zone name'),
             normalizer=lambda value: value.lower(),
         ),
         Str('criteria?',
             cli_name='criteria',
-            doc='search criteria',
+            label=_('Search criteria'),
         ),
     )
 
     takes_options = (
         Str('idnsname?',
             cli_name='resource',
-            doc='resource name',
+            label=_('Resource name'),
             default_from=lambda zone: zone.lower(),
         ),
         StrEnum('type?',
-            cli_name='type',
-            doc='record type',
+            label=_('Record type'),
             values=_record_types,
         ),
         Str('data?',
-            cli_name='data',
-            doc='type-specific data',
+            label=_('type-specific data'),
         ),
     )
 
@@ -785,15 +780,15 @@ class dns_show_rr(Command):
     """
     Show existing DNS resource records.
     """
+
     takes_args = (
         Str('zone',
-            cli_name='zone',
-            doc='zone name',
+            label=_('Zone name'),
             normalizer=lambda value: value.lower(),
         ),
         Str('idnsname',
             cli_name='resource',
-            doc='resource name',
+            label=_('Resource name'),
             normalizer=lambda value: value.lower(),
         ),
     )
diff --git a/ipalib/plugins/group.py b/ipalib/plugins/group.py
index a04330c..896e26e 100644
--- a/ipalib/plugins/group.py
+++ b/ipalib/plugins/group.py
@@ -60,38 +60,38 @@ class group(LDAPObject):
     takes_params = (
         Str('cn',
             cli_name='name',
-            label='Group name',
+            label=_('Group name'),
             primary_key=True,
             normalizer=lambda value: value.lower(),
         ),
         Str('description',
             cli_name='desc',
-            label='Description',
-            doc='Group description',
+            label=_('Description'),
+            doc=_('Group description'),
         ),
         Int('gidnumber?',
             cli_name='gid',
-            label='GID',
-            doc='GID (use this option to set it manually)',
+            label=_('GID'),
+            doc=_('GID (use this option to set it manually)'),
         ),
         Str('member_group?',
-            label='Member Groups',
+            label=_('Member groups'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('member_user?',
-            label='Member Users',
+            label=_('Member users'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('member?',
-            label='Failed Members',
+            label=_('Failed members'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('user?',
-            label='Users',
+            label=_('Users'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('group?',
-            label='Groups',
+            label=_('Groups'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
@@ -109,7 +109,7 @@ class group_add(LDAPCreate):
     takes_options = LDAPCreate.takes_options + (
         Flag('posix',
              cli_name='posix',
-             doc='create as posix group?',
+             doc=_('Create as posix group?'),
         ),
     )
 
diff --git a/ipalib/plugins/hbac.py b/ipalib/plugins/hbac.py
index 29567cf..7fbabdc 100644
--- a/ipalib/plugins/hbac.py
+++ b/ipalib/plugins/hbac.py
@@ -64,41 +64,45 @@ class hbac(LDAPObject):
     takes_params = (
         Str('cn',
             cli_name='name',
-            doc='rule name',
+            label=_('Rule name'),
             primary_key=True,
         ),
         StrEnum('accessruletype',
             cli_name='type',
-            doc='rule type (allow or deny)',
+            label=_('Rule type (allow or deny)'),
             values=(u'allow', u'deny'),
         ),
         Str('servicename?',
             cli_name='service',
-            doc='name of service the rule applies to (e.g. ssh)',
+            label=_('Service name'),
+            doc=_('Name of service the rule applies to (e.g. ssh)'),
         ),
         # FIXME: {user,host,sourcehost}categories should expand in the future
         StrEnum('usercategory?',
             cli_name='usercat',
-            doc='user category the rule applies to',
+            label=_('User category'),
+            doc=_('User category the rule applies to'),
             values=(u'all', ),
         ),
         StrEnum('hostcategory?',
             cli_name='hostcat',
-            doc='host category the rule applies to',
+            label=_('Host category'),
+            doc=_('Host category the rule applies to'),
             values=(u'all', ),
         ),
         StrEnum('sourcehostcategory?',
             cli_name='srchostcat',
-            doc='source host category the rule applies to',
+            label=_('Source host category'),
+            doc=_('Source host category the rule applies to'),
             values=(u'all', ),
         ),
         AccessTime('accesstime?',
             cli_name='time',
-            doc='access time',
+            label=_('Access time'),
         ),
         Str('description?',
             cli_name='desc',
-            doc='description',
+            label=_('Description'),
         ),
     )
 
@@ -224,10 +228,11 @@ class hbac_add_accesstime(LDAPQuery):
     """
     Add access time to HBAC rule.
     """
+
     takes_options = (
         AccessTime('accesstime',
             cli_name='time',
-            doc='access time',
+            label=_('Access time'),
         ),
     )
 
@@ -265,7 +270,7 @@ class hbac_remove_accesstime(LDAPQuery):
     takes_options = (
         AccessTime('accesstime?',
             cli_name='time',
-            doc='access time',
+            label=_('Access time'),
         ),
     )
 
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index c459cfe..13bb743 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -84,58 +84,59 @@ class host(LDAPObject):
     takes_params = (
         Str('fqdn', validate_host,
             cli_name='hostname',
-            label='Hostname',
+            label=_('Host name'),
             primary_key=True,
             normalizer=lambda value: value.lower(),
         ),
         Str('description?',
             cli_name='desc',
-            label='Description',
-            doc='Description of the host',
+            label=_('Description'),
+            doc=_('A description of this host'),
         ),
         Str('l?',
             cli_name='locality',
-            label='Locality',
-            doc='Locality of the host (Baltimore, MD)',
+            label=_('Locality'),
+            doc=_('Host locality (e.g. "Baltimore, MD")'),
         ),
         Str('nshostlocation?',
             cli_name='location',
-            label='Location',
-            doc='Location of the host (e.g. Lab 2)',
+            label=_('Location'),
+            doc=_('Host location (e.g. "Lab 2")'),
         ),
         Str('nshardwareplatform?',
             cli_name='platform',
-            label='Platform',
-            doc='Hardware platform of the host (e.g. Lenovo T61)',
+            label=_('Platform'),
+            doc=_('Host hardware platform (e.g. "Lenovo T61")'),
         ),
         Str('nsosversion?',
             cli_name='os',
-            label='Operating system',
-            doc='Operating System and version of the host (e.g. Fedora 9)',
+            label=_('Operating system'),
+            doc=_('Host operating system and version (e.g. "Fedora 9")'),
         ),
         Str('userpassword?',
             cli_name='password',
-            label='User password',
-            doc='Password used in bulk enrollment',
+            label=_('User password'),
+            doc=_('Password used in bulk enrollment'),
         ),
         Bytes('usercertificate?', validate_certificate,
             cli_name='certificate',
-            doc='base-64 encoded server certificate',
+            label=_('Certificate'),
+            doc=_('Base-64 encoded server certificate'),
         ),
         Str('krbprincipalname?',
-            label='Principal Name',
+            label=_('Principal name'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('memberof_hostgroup?',
-            label='Member of Host Groups',
+            label=_('Member of host-groups'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('memberof_netgroup?',
-            label='Member Net Groups',
+            label=_('Member of net-groups'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('memberof_rolegroup?',
-            label='Member of Role Groups',
+            label=_('Member of role-groups'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
@@ -226,7 +227,8 @@ class host_mod(LDAPUpdate):
     takes_options = LDAPUpdate.takes_options + (
         Str('krbprincipalname?',
             cli_name='principalname',
-            doc='Kerberos principal name for this host',
+            label=_('Principal name'),
+            doc=_('Kerberos principal name for this host'),
             attribute=True,
         ),
     )
diff --git a/ipalib/plugins/hostgroup.py b/ipalib/plugins/hostgroup.py
index 5a723b8..698b395 100644
--- a/ipalib/plugins/hostgroup.py
+++ b/ipalib/plugins/hostgroup.py
@@ -51,26 +51,26 @@ class hostgroup(LDAPObject):
     takes_params = (
         Str('cn',
             cli_name='name',
-            label='Hostgroup name',
-            doc='group name',
+            label=_('Host-group'),
+            doc=_('Name of host-group'),
             primary_key=True,
             normalizer=lambda value: value.lower(),
         ),
         Str('description',
             cli_name='desc',
-            label='Description',
-            doc='A description of this group',
+            label=_('Description'),
+            doc=_('A description of this host-group'),
         ),
         Str('member_host?',
-            label='Member Hosts',
+            label=_('Member hosts'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('member_hostgroup?',
-            label='Member Host Groups',
+            label=_('Member host-groups'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('memberof_hostgroup?',
-            label='Member of Hostgroups',
+            label=_('Member of host-groups'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
diff --git a/ipalib/plugins/krbtpolicy.py b/ipalib/plugins/krbtpolicy.py
index 8aa8f0c..ada7eff 100644
--- a/ipalib/plugins/krbtpolicy.py
+++ b/ipalib/plugins/krbtpolicy.py
@@ -23,6 +23,7 @@ Kerberos ticket policy
 from ipalib import api
 from ipalib import Int, Str
 from ipalib.plugins.baseldap import *
+from ipalib import _
 
 
 # FIXME: load this from a config file?
@@ -47,16 +48,19 @@ class krbtpolicy(LDAPObject):
     takes_params = (
         Str('uid?',
             cli_name='user',
-            doc='manage ticket policy for specific user',
+            label=_('User name'),
+            doc=_('Manage ticket policy for specific user'),
             primary_key=True,
         ),
         Int('krbmaxticketlife?',
             cli_name='maxlife',
-            doc='maximum ticket life',
+            label=_('Max life'),
+            doc=_('Maximum ticket life'),
         ),
         Int('krbmaxrenewableage?',
             cli_name='maxrenew',
-            doc='maximum renewable age',
+            label=_('Max renew'),
+            doc=_('Maximum renewable age'),
         ),
     )
 
@@ -141,4 +145,3 @@ class krbtpolicy_reset(LDAPQuery):
         return dict(result=entry_attrs, value=u'')
 
 api.register(krbtpolicy_reset)
-
diff --git a/ipalib/plugins/migration.py b/ipalib/plugins/migration.py
index b509675..5ae6356 100644
--- a/ipalib/plugins/migration.py
+++ b/ipalib/plugins/migration.py
@@ -31,6 +31,7 @@ from ipalib import api, errors, output, uuid
 from ipalib import Command, List, Password, Str
 from ipalib.cli import to_cli
 from ipaserver.plugins.ldap2 import ldap2
+from ipalib import _
 
 
 # USER MIGRATION CALLBACKS AND VARS
@@ -72,7 +73,7 @@ def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx):
         entry_attrs['krbprincipalname'] = principal
     else:
         failed[pkey] = _krb_err_msg % principal
- 
+
     return dn
 
 
@@ -93,7 +94,7 @@ def _pre_migrate_group(ldap, pkey, dn, entry_attrs, failed, config, ctx):
         """
         new_members = []
         entry_attrs.setdefault(member_attr, [])
-        for m in entry_attrs[member_attr]: 
+        for m in entry_attrs[member_attr]:
             col = m.find(',')
             if col == -1:
                 continue
@@ -162,7 +163,8 @@ class migrate_ds(Command):
     takes_args = (
         Str('ldapuri', validate_ldapuri,
             cli_name='ldap_uri',
-            doc='LDAP URI of DS server to migrate from',
+            label=_('LDAP URI'),
+            doc=_('LDAP URI of DS server to migrate from'),
         ),
         Password('bindpw',
             cli_name='password',
@@ -173,19 +175,21 @@ class migrate_ds(Command):
     takes_options = (
         Str('binddn?',
             cli_name='bind_dn',
-            doc='bind DN',
+            label=_('Bind DN'),
             default=u'cn=directory manager',
             autofill=True,
         ),
         Str('usercontainer?',
             cli_name='user_container',
-            doc='RDN of container for users in DS',
+            label=_('User container'),
+            doc=_('RDN of container for users in DS'),
             default=u'ou=people',
             autofill=True,
         ),
         Str('groupcontainer?',
             cli_name='group_container',
-            doc='RDN of container for groups in DS',
+            label=_('Group container'),
+            doc=_('RDN of container for groups in DS'),
             default=u'ou=groups',
             autofill=True,
         ),
@@ -371,4 +375,3 @@ class migrate_ds(Command):
         textui.print_plain(self.pwd_migration_msg)
 
 api.register(migrate_ds)
-
diff --git a/ipalib/plugins/netgroup.py b/ipalib/plugins/netgroup.py
index 767bc1b..74c1699 100644
--- a/ipalib/plugins/netgroup.py
+++ b/ipalib/plugins/netgroup.py
@@ -56,27 +56,25 @@ class netgroup(LDAPObject):
     takes_params = (
         Str('cn',
             cli_name='name',
-            label='Netgroup name',
-            doc='netgroup name',
+            label=_('Netgroup name'),
             primary_key=True,
             normalizer=lambda value: value.lower(),
         ),
         Str('description',
             cli_name='desc',
-            label='Description',
-            doc='netgroup description',
+            label=_('Description'),
+            doc=_('Netgroup description'),
         ),
         Str('nisdomainname?',
             cli_name='nisdomain',
-            label='NIS domain name',
-            doc='NIS domain name',
+            label=_('NIS domain name'),
         ),
         Str('member_host?',
-            label='Member Host',
+            label=_('Member host'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('externalhost?',
-            label='External Host',
+            label=_('External host'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
diff --git a/ipalib/plugins/passwd.py b/ipalib/plugins/passwd.py
index 6c509c2..50e99c2 100644
--- a/ipalib/plugins/passwd.py
+++ b/ipalib/plugins/passwd.py
@@ -23,16 +23,18 @@ Password changes
 from ipalib import api, errors, util
 from ipalib import Command
 from ipalib import Str, Password
+from ipalib import _
 
 
 class passwd(Command):
     """
     Change user password.
     """
+
     takes_args = (
         Str('principal',
             cli_name='user',
-            doc='username',
+            label=_('User name'),
             primary_key=True,
             autofill=True,
             create_default=lambda **kw: util.get_current_principal(),
diff --git a/ipalib/plugins/pwpolicy.py b/ipalib/plugins/pwpolicy.py
index 396a1c7..a10d07d 100644
--- a/ipalib/plugins/pwpolicy.py
+++ b/ipalib/plugins/pwpolicy.py
@@ -118,41 +118,41 @@ class pwpolicy(Object):
 
     takes_params = (
         Str('cn?',
-            label='Group',
+            label=_('Group'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Int('krbmaxpwdlife?',
             cli_name='maxlife',
-            doc='Max. Password Lifetime (days)',
-            label='Maximum lifetime (in days)',
+            label=_('Max lifetime (days)'),
+            doc=_('Maximum password lifetime (in days)'),
             minvalue=0,
             attribute=True,
         ),
         Int('krbminpwdlife?',
             cli_name='minlife',
-            doc='Min. Password Lifetime (hours)',
-            label='Mininum lifetime (in hours)',
+            label=_('Min lifetime (hours)'),
+            doc=_('Minimum password lifetime (in hours)'),
             minvalue=0,
             attribute=True,
         ),
         Int('krbpwdhistorylength?',
             cli_name='history',
-            doc='Password History Size',
-            label='Password History Size',
+            label=_('History size'),
+            doc=_('Password history size'),
             minvalue=0,
             attribute=True,
         ),
         Int('krbpwdmindiffchars?',
             cli_name='minclasses',
-            doc='Min. Number of Character Classes',
-            label='Min. Number of Character Classes',
+            label=_('Character classes'),
+            doc=_('Minimum number of character classes'),
             minvalue=0,
             attribute=True,
         ),
         Int('krbpwdminlength?',
             cli_name='minlength',
-            doc='Min. Length of Password',
-            label='Min. Length of Password',
+            label=_('Min length'),
+            doc=_('Minimum length of password'),
             minvalue=0,
             attribute=True,
         ),
@@ -167,15 +167,17 @@ class pwpolicy_add(crud.Create):
     """
 
     msg_summary = _('Added policy for group "%(value)s"')
+
     takes_options = (
         Str('group',
-            doc='Group to set policy for',
+            label=_('Group'),
+            doc=_('Group to set policy for'),
             attribute=False,
         ),
         Int('cospriority',
             cli_name='priority',
-            label='Priority',
-            doc='Priority of the policy. Higher number equals lower priority',
+            label=_('Priority'),
+            doc=_('Priority of the policy (higher number equals lower priority)'),
             minvalue=0,
             attribute=True,
         ),
@@ -220,12 +222,13 @@ class pwpolicy_mod(crud.Update):
     msg_summary = _('Modified policy for group "%(value)s"')
     takes_options = (
         Str('group?',
-            doc='Group to set policy for',
+            label=_('Group'),
+            doc=_('Group to set policy for'),
             attribute=False,
         ),
         Int('cospriority?',
-            cli_name='priority',
-            doc='Priority of the policy. Higher number equals lower priority',
+            label=_('Priority'),
+            doc=_('Priority of the policy (higher number equals lower priority)'),
             minvalue=0,
             attribute=True,
         ),
@@ -315,10 +318,12 @@ class pwpolicy_show(Method):
     )
     takes_options = (
         Str('group?',
-            doc='Group to display policy',
+            label=_('Group'),
+            doc=_('Group to display policy'),
         ),
         Str('user?',
-            doc='Display policy applied to a given user',
+            label=_('User'),
+            doc=_('Display policy applied to a given user'),
         ),
     )
 
diff --git a/ipalib/plugins/rolegroup.py b/ipalib/plugins/rolegroup.py
index bf21e23..112999f 100644
--- a/ipalib/plugins/rolegroup.py
+++ b/ipalib/plugins/rolegroup.py
@@ -52,26 +52,25 @@ class rolegroup(LDAPObject):
     takes_params = (
         Str('cn',
             cli_name='name',
-            label='Name',
-            doc='rolegroup name',
+            label=_('Role-group name'),
             primary_key=True,
             normalizer=lambda value: value.lower(),
         ),
         Str('description',
             cli_name='desc',
-            label='Description',
-            doc='A description of this rolegroup',
+            label=_('Description'),
+            doc=_('A description of this role-group'),
         ),
         Str('member_group?',
-            label='Member Groups',
+            label=_('Member groups'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('member_user?',
-            label='Member Users',
+            label=_('Member users'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('memberof_taskgroup?',
-            label='Member of Task Groups',
+            label=_('Member of task-groups'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
diff --git a/ipalib/plugins/service.py b/ipalib/plugins/service.py
index d7c795b..d72a42d 100644
--- a/ipalib/plugins/service.py
+++ b/ipalib/plugins/service.py
@@ -123,16 +123,16 @@ class service(LDAPObject):
 
     takes_params = (
         Str('krbprincipalname', validate_principal,
-            label='Principal',
             cli_name='principal',
-            doc='service principal',
+            label=_('Principal'),
+            doc=_('Service principal'),
             primary_key=True,
             normalizer=lambda value: normalize_principal(value),
         ),
         Bytes('usercertificate?', validate_certificate,
-            label='Certificate',
             cli_name='certificate',
-            doc='base-64 encoded server certificate',
+            label=_('Certificate'),
+            doc=_('Base-64 encoded server certificate'),
         ),
     )
 
diff --git a/ipalib/plugins/taskgroup.py b/ipalib/plugins/taskgroup.py
index afdbf65..0927c3d 100644
--- a/ipalib/plugins/taskgroup.py
+++ b/ipalib/plugins/taskgroup.py
@@ -52,26 +52,25 @@ class taskgroup(LDAPObject):
     takes_params = (
         Str('cn',
             cli_name='name',
-            label='Taskgroup name',
-            doc='taskgroup name',
+            label=_('Task-group name'),
             primary_key=True,
             normalizer=lambda value: value.lower(),
         ),
         Str('description',
             cli_name='desc',
-            label='Description',
-            doc='taskgroup description',
+            label=_('Description'),
+            doc=_('Task-group description'),
         ),
         Str('member_group?',
-            label='Member Groups',
+            label=_('Member groups'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('member_user?',
-            label='Member Users',
+            label=_('Member users'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
         Str('member_rolegroup?',
-            label='Member Role Groups',
+            label=_('Member role-groups'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
index 00d64c7..2b5c76c 100644
--- a/ipalib/plugins/user.py
+++ b/ipalib/plugins/user.py
@@ -73,63 +73,63 @@ class user(LDAPObject):
     takes_params = (
         Str('uid',
             cli_name='login',
-            label='User login',
+            label=_('User login'),
             primary_key=True,
             default_from=lambda givenname, sn: givenname[0] + sn,
             normalizer=lambda value: value.lower(),
         ),
         Str('givenname',
             cli_name='first',
-            label='First name',
+            label=_('First name'),
         ),
         Str('sn',
             cli_name='last',
-            label='Last name',
+            label=_('Last name'),
         ),
         Str('homedirectory?',
             cli_name='homedir',
-            label='Home directory',
+            label=('Home directory'),
             default_from=lambda uid: '/home/%s' % uid,
         ),
         Str('gecos?',
-            label='GECOS field',
+            label=_('GECOS field'),
             default_from=lambda uid: uid,
             autofill=True,
         ),
         Str('loginshell?',
             cli_name='shell',
-            label='Login shell',
+            label=_('Login shell'),
             default=u'/bin/sh',
         ),
         Str('krbprincipalname?',
             cli_name='principal',
-            label='Kerberos principal',
+            label=_('Kerberos principal'),
             default_from=lambda uid: '%...@%s' % (uid, api.env.realm),
             autofill=True,
         ),
         Str('mail?',
             cli_name='email',
-            label='Email address',
+            label=_('Email address'),
         ),
         Password('userpassword?',
             cli_name='password',
-            label='Password',
-            doc='Set the user password',
+            label=_('Password'),
+            doc=_('Set the user password'),
             # FIXME: This is temporary till bug is fixed causing updates to
             # bomb out via the webUI.
             exclude='webui',
         ),
         Int('uidnumber?',
             cli_name='uid',
-            label='UID',
-            doc='UID (use this option to set it manually)',
+            label=_('UID'),
+            doc=_('UID (use this option to set it manually)'),
         ),
         Str('street?',
             cli_name='street',
-            label='Street address',
+            label=_('Street address'),
         ),
         Str('memberof_group?',
-            label='Groups',
+            label=_('Groups'),
             flags=['no_create', 'no_update', 'no_search'],
         ),
     )
diff --git a/ipalib/text.py b/ipalib/text.py
index 07f1b21..cabca43 100644
--- a/ipalib/text.py
+++ b/ipalib/text.py
@@ -34,28 +34,25 @@ class LazyText(object):
         return self.__unicode__() % kw
 
 
-class FixMe(LazyText):
-    def __init__(self, msg):
-        self.msg = msg
-        super(FixMe, self).__init__()
-
-    def __repr__(self):
-        return '%s(%r)' % (self.__class__.__name__, self.msg)
-
-    def __unicode__(self):
-        return u'<%s>' % self.msg
-
-
 class Gettext(LazyText):
-    def __init__(self, msg, domain, localedir):
+    def __init__(self, msg, domain=None, localedir=None):
         self.msg = msg
         super(Gettext, self).__init__(domain, localedir)
 
     def __unicode__(self):
         return self.msg.decode('utf-8')
 
+    def __repr__(self):
+        return '%s(%r)' % (self.__class__.__name__, self.msg)
+
+    def __json__(self):
+        return self.__unicode__()
 
 
+class FixMe(Gettext):
+    def __unicode__(self):
+        return u'<%s>' % self.msg
+
 
 class NGettext(LazyText):
     def __init__(self, singular, plural, domain, localedir):
diff --git a/tests/test_ipalib/test_parameters.py b/tests/test_ipalib/test_parameters.py
index c4b2d75..b5a01fd 100644
--- a/tests/test_ipalib/test_parameters.py
+++ b/tests/test_ipalib/test_parameters.py
@@ -174,8 +174,8 @@ class test_Param(ClassChecker):
 
         # Test default kwarg values:
         assert o.cli_name is name
-        assert o.label == '<my_param>'
-        assert o.doc == '<my_param>'
+        assert o.label.msg == 'my_param'
+        assert o.doc.msg == 'my_param'
         assert o.required is True
         assert o.multivalue is False
         assert o.primary_key is False
@@ -193,7 +193,7 @@ class test_Param(ClassChecker):
 
         # Test that doc defaults from label:
         o = self.cls('my_param', doc='Hello world')
-        assert o.label == '<my_param>'
+        assert o.label.msg == 'my_param'
         assert o.doc == 'Hello world'
 
         o = self.cls('my_param', label='My Param')
-- 
1.6.3.3

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to