Пример #1
0
class EntitySchema(Schema):
    allow_extra_fields = True
    name = All(validators.String(min=0, max=5000), AvailableName())
    attributes = AttributeSchema()
    reviewed = validators.StringBool(if_empty=False, if_missing=False)
    invalid = validators.StringBool(if_empty=False, if_missing=False)
    canonical = ValidCanonicalEntity(if_missing=None, if_empty=None)
Пример #2
0
class DatasetEditSchema(Schema):
    label = validators.String(min=3, max=255)
    algorithm = validators.String(min=3, max=255)
    match_aliases = validators.StringBool(if_missing=False)
    ignore_case = validators.StringBool(if_missing=False)
    public_edit = validators.StringBool(if_missing=False)
    normalize_text = validators.StringBool(if_missing=False)
    enable_invalid = validators.StringBool(if_missing=False)
Пример #3
0
class DatasetEditSchema(Schema):
    allow_extra_fields = True
    label = validators.String(min=3, max=255)
    match_aliases = validators.StringBool(if_missing=False)
    ignore_case = validators.StringBool(if_missing=False)
    public_edit = validators.StringBool(if_missing=False)
    normalize_text = validators.StringBool(if_missing=False)
    enable_invalid = validators.StringBool(if_missing=False)
Пример #4
0
class InstanceVotingEditForm(formencode.Schema):
    allow_extra_fields = True
    allow_adopt = validators.StringBool(not_empty=False, if_empty=False,
                                        if_missing=False)
    allow_delegate = validators.StringBool(not_empty=False, if_empty=False,
                                           if_missing=False)
    activation_delay = validators.Int(not_empty=True)
    required_majority = validators.Number(not_empty=True)
Пример #5
0
class InstanceGeneralEditForm(formencode.Schema):
    allow_extra_fields = True
    label = validators.String(min=4, max=254, not_empty=True)
    description = validators.String(max=100000, if_empty=None, not_empty=False)
    locale = validators.String(not_empty=False)
    default_group = forms.ValidInstanceGroup(not_empty=True)
    hidden = validators.StringBool(not_empty=False, if_empty=False,
                                   if_missing=False)
    is_authenticated = validators.StringBool(not_empty=False, if_empty=False,
                                          if_missing=False)
Пример #6
0
class InstanceVotingEditForm(formencode.Schema):
    allow_extra_fields = True
    allow_delegate = validators.StringBool(not_empty=False, if_empty=False,
                                           if_missing=False)
    if not config.get_bool('adhocracy.hide_final_adoption_votings'):
        allow_adopt = validators.StringBool(not_empty=False, if_empty=False,
                                            if_missing=False)
        activation_delay = validators.Int(not_empty=True)
        required_majority = validators.Number(not_empty=True)
    votedetail_badges = forms.ValidUserBadges()
Пример #7
0
class InstanceEditForm(formencode.Schema):
    allow_extra_fields = True
    label = validators.String(min=4, max=254, not_empty=True)
    description = validators.String(max=100000, if_empty=None, not_empty=False)
    activation_delay = validators.Int(not_empty=True)
    required_majority = validators.Number(not_empty=True)
    default_group = forms.ValidGroup(not_empty=True)
    locale = validators.String(not_empty=False)
    allow_adopt = validators.StringBool(not_empty=False,
                                        if_empty=False,
                                        if_missing=False)
    allow_delegate = validators.StringBool(not_empty=False,
                                           if_empty=False,
                                           if_missing=False)
    allow_propose = validators.StringBool(not_empty=False,
                                          if_empty=False,
                                          if_missing=False)
    allow_index = validators.StringBool(not_empty=False,
                                        if_empty=False,
                                        if_missing=False)
    use_norms = validators.StringBool(not_empty=False,
                                      if_empty=False,
                                      if_missing=False)
    require_selection = validators.StringBool(not_empty=False,
                                              if_empty=False,
                                              if_missing=False)
    hidden = validators.StringBool(not_empty=False,
                                   if_empty=False,
                                   if_missing=False)
    frozen = validators.StringBool(not_empty=False,
                                   if_empty=False,
                                   if_missing=False)
    milestones = validators.StringBool(not_empty=False,
                                       if_empty=False,
                                       if_missing=False)
Пример #8
0
class MassmessageProposalForm(MassmessageBaseForm):
    creators = validators.StringBool(not_empty=False,
                                     if_empty=False,
                                     if_missing=False)
    supporters = validators.StringBool(not_empty=False,
                                       if_empty=False,
                                       if_missing=False)
    opponents = validators.StringBool(not_empty=False,
                                      if_empty=False,
                                      if_missing=False)
    chained_validators = [
        forms.ProposalMessageNoRecipientGroup(),
    ]
Пример #9
0
class RootController(BaseController):
    @expose()
    def index(self, **kw):
        now = datetime.utcnow()
        redirect(c.app.url + now.strftime('%Y/%m/%d/'))

    @expose('jinja:forgechat:templates/chat/search.html')
    @validate(
        dict(q=validators.UnicodeString(if_empty=None),
             history=validators.StringBool(if_empty=False)))
    def search(self, q=None, history=None, **kw):
        'local tool search'
        results = []
        count = 0
        if not q:
            q = ''
        else:
            results = search(q,
                             fq=[
                                 'is_history_b:%s' % history,
                                 'project_id_s:%s' % c.project._id,
                                 'mount_point_s:%s' %
                                 c.app.config.options.mount_point
                             ])
            if results: count = results.hits
        return dict(q=q, history=history, results=results or [], count=count)

    @expose()
    def _lookup(self, y, m, d, *rest):
        y, m, d = int(y), int(m), int(d)
        return DayController(date(y, m, d)), rest
Пример #10
0
class SearchController(BaseController):
    @expose('jinja:allura:templates/search_index.html')
    @validate(dict(q=V.UnicodeString(), history=V.StringBool(if_empty=False)))
    @with_trailing_slash
    def index(self, q=None, history=None, **kw):
        c.search_results = SearchResults()
        c.help_modal = SearchHelp(comments=False)
        pids = [c.project._id] + [p._id for p in c.project.subprojects]
        project_match = ' OR '.join(map(str, pids))
        search_params = kw
        search_params.update({
            'q':
            q,
            'history':
            history,
            'app':
            False,
            'fq': [
                'project_id_s:(%s)' % project_match,
                '-deleted_b:true',
            ],
        })
        d = search_app(**search_params)
        d['search_comments_disable'] = True
        d['hide_app_project_switcher'] = True
        return d
Пример #11
0
class RegisterSchema(Schema):
    filter_extra_fields = True
    allow_extra_fields = True
    name = validators.UnicodeString(not_empty=True, strip=True)
    nickname = validators.PlainText(strip=True,
                                    if_empty='',
                                    if_missing='',
                                    if_invalid='')
    gender = validators.Int(min=0,
                            max=3,
                            if_empty=0,
                            if_missing=0,
                            if_invalid=0)
    email = All(validators.Email(not_empty=True, strip=True), UniqueEmail())
    phoneNumber = national.USPhoneNumber(strip=True,
                                         if_empty='',
                                         if_missing='',
                                         if_invalid='')
    password = validators.String(not_empty=True)
    graduationYear = validators.Int(min=1967, not_empty=True)
    biography = validators.UnicodeString(strip=True,
                                         if_empty=u'',
                                         if_missing=u'',
                                         if_invalid=u'')
    active = validators.StringBool(if_empty=False,
                                   if_missing=False,
                                   if_invalid=False,
                                   strip=True)
    recaptcha_challenge_field = validators.String(strip=True, not_empty=True)
    recaptcha_response_field = RecaptchaValidator(strip=True, not_empty=True)
    _csrf = validators.String(strip=True, not_empty=True)
Пример #12
0
class CreateSiteNotificationSchema(fe.Schema):
    active = fev.StringBool(if_missing=False)
    impressions = fev.Int(not_empty=True)
    content = fev.UnicodeString(not_empty=True)
    user_role = fev.FancyValidator(not_empty=False, if_empty=None)
    page_regex = fev.FancyValidator(not_empty=False, if_empty=None)
    page_tool_type = fev.FancyValidator(not_empty=False, if_empty=None)
Пример #13
0
class RootController(BaseController):

    @expose()
    def index(self, **kw):
        now = datetime.utcnow()
        redirect(c.app.url + now.strftime('%Y/%m/%d/'))

    @with_trailing_slash
    @expose('jinja:forgechat:templates/chat/search.html')
    @validate(dict(q=validators.UnicodeString(if_empty=None),
                   project=validators.StringBool(if_empty=False)))
    def search(self, q=None, project=None, limit=None, page=0, **kw):
        c.search_results = SearchResults()
        c.help_modal = SearchHelp(comments=False, history=False)
        search_params = kw
        search_params.update({
            'q': q or '',
            'project': project,
            'limit': limit,
            'page': page,
            'allowed_types': ['Chat Message'],
        })
        d = search_app(**search_params)
        d['search_comments_disable'] = True
        d['search_history_disable'] = True
        return d

    @expose()
    def _lookup(self, y, m, d, *rest):
        y,m,d = int(y), int(m), int(d)
        return DayController(date(y,m,d)), rest
Пример #14
0
 def fields(self):
     fields = [
         ew.TextField(name='summary',
                      label='Title',
                      attrs={
                          'style': 'width: 425px',
                          'class': 'memorable',
                          'placeholder': 'Title'
                      },
                      validator=fev.UnicodeString(
                          not_empty=True,
                          messages={'empty': "You must provide a Title"})),
         ffw.MarkdownEdit(label='Description',
                          name='description',
                          attrs={'style': 'width: 95%'}),
         ew.SingleSelectField(
             name='status',
             label='Status',
             options=lambda: c.app.globals.all_status_names.split()),
         ffw.ProjectUserCombo(name='assigned_to', label='Owner'),
         ffw.LabelEdit(label='Labels',
                       name='labels',
                       className='ticket_form_tags'),
         ew.Checkbox(name='private',
                     label='Mark as Private',
                     validator=v.AnonymousValidator(),
                     attrs={'class': 'unlabeled'}),
         ew.Checkbox(name='discussion_disabled',
                     label='Discussion Disabled',
                     validator=fev.StringBool(),
                     attrs={'class': 'unlabeled'}),
         ew.InputField(
             name='attachment',
             label='Attachment',
             field_type='file',
             attrs={'multiple': 'True'},
             validator=fev.FieldStorageUploadConverter(if_missing=None)),
         ffw.MarkdownEdit(name='comment',
                          label='Comment',
                          attrs={'style': 'min-height:7em; width:97%'}),
         ew.SubmitButton(
             label=self.submit_text,
             name='submit',
             attrs={
                 'class':
                 "ui-button ui-widget ui-state-default ui-button-text-only"
             }),
         ew.HiddenField(name='ticket_num',
                        validator=fev.Int(if_missing=None)),
         ew.Checkbox(name='subscribe', label='Subscribe'),
     ]
     # milestone is kind of special because of the layout
     # add it to the main form rather than handle with the other customs
     if c.app.globals.custom_fields:
         for cf in c.app.globals.custom_fields:
             if cf.name == '_milestone':
                 fields.append(TicketCustomField.make(cf))
                 break
     return ew_core.NameList(fields)
Пример #15
0
class CommentNewForm(formencode.Schema):
    allow_extra_fields = True
    topic = forms.ValidDelegateable()
    reply = forms.ValidComment(if_empty=None, if_missing=None)
    wiki = validators.StringBool(not_empty=False, if_empty=False,
                                 if_missing=False)
    variant = forms.VariantName(not_empty=False, if_empty=model.Text.HEAD,
                                if_missing=model.Text.HEAD)
Пример #16
0
    class DatastoreSchema(schema.Schema):
        allow_extra_fields = True

        uri = validators.UnicodeString(if_missing=None, if_empty=None)
        database = validators.UnicodeString(if_missing=None, if_empty=None)
        connect_retry = validators.Number(if_missing=3, if_empty=0)
        auto_ensure_indexes = validators.StringBool(if_missing=True)
        # pymongo
        tz_aware = validators.Bool(if_missing=False)
Пример #17
0
class DefaultWithArgsAndValidatorsController(TGController):
    @expose()
    def failure(self, *args, **kw):
        return "failure"

    @expose()
    @validate(dict(a=validators.Int(), b=validators.StringBool()),
              error_handler=failure)
    def _default(self, a, b=None, **kw):
        return "default with args and validators %s %s" % (a, b)
Пример #18
0
class LayoutBaseSchema(Schema):
    if_key_missing = None

    Owner = ciocvalidators.AgencyCodeValidator()

    AlmostStandardsMode = validators.StringBool(if_empty=False)
    LayoutCSS = ciocvalidators.UnicodeString()
    LayoutCSSURL = ciocvalidators.Url(max=255)
    UseFontAwesome = validators.Bool()
    UseFullCIOCBootstrap = validators.Bool()
Пример #19
0
class DatastoreSchema(schema.Schema):
    uri=validators.UnicodeString(if_missing=None, if_empty=None)
    database=validators.UnicodeString(if_missing=None, if_empty=None)
    authenticate=AuthenticateSchema(if_missing=None, if_empty=None)
    connect_retry=validators.Number(if_missing=3, if_empty=0)
    use_greenlets = validators.Bool(if_missing=False)
    auto_ensure_indexes = validators.StringBool(if_missing=True)
    # pymongo
    tz_aware=validators.Bool(if_missing=False)
    slave_okay=validators.Bool(if_missing=False)
    max_pool_size=validators.Int(if_missing=10)
Пример #20
0
class SetAnswersSchema(CSRFSchema):
    """The :class:`~wte.views.quiz.SetAnswersSchema` validates requests to
    store a new answer for a :class:`~wte.text_formatter.docutils_ext.Quiz`.
    """

    quiz = validators.UnicodeString(not_empty=True)
    """The :class:`~wte.models.Quiz` name."""
    question = validators.UnicodeString(not_empty=True)
    """The :class:`~wte.models.Quiz` question."""
    answer = ForEach(validators.UnicodeString(if_empty='', if_missing=''))
    """The answer (can be given multiple times for multiple answers)."""
    correct = validators.StringBool(not_empty=True,
                                    if_missing=False,
                                    if_empty=False)
    """Whether the answer is correct or not."""
Пример #21
0
class SearchController(BaseController):
    @expose('jinja:allura:templates/search_index.html')
    @validate(dict(q=V.UnicodeString(), history=V.StringBool(if_empty=False)))
    @with_trailing_slash
    def index(self, q=None, history=False, **kw):
        c.search_results = W.search_results
        search_params = kw
        search_params.update({
            'q': q,
            'history': history,
            'app': False,
        })
        d = search_app(**search_params)
        d['search_comments_disable'] = True
        d['hide_app_project_switcher'] = True
        return d
Пример #22
0
class UserUpdateForm(formencode.Schema):
    allow_extra_fields = True
    display_name = validators.String(not_empty=False)
    email = validators.Email(not_empty=True)
    locale = validators.String(not_empty=False)
    password_change = validators.String(not_empty=False)
    password_confirm = validators.String(not_empty=False)
    chained_validators = [validators.FieldsMatch(
        'password_change', 'password_confirm')]
    bio = validators.String(max=1000, min=0, not_empty=False)
    no_help = validators.StringBool(not_empty=False, if_empty=False,
                                    if_missing=False)
    page_size = validators.Int(min=1, max=100, not_empty=False,
                               if_empty=10, if_missing=10)
    email_priority = validators.Int(min=0, max=6, not_empty=False,
                                    if_missing=3)
Пример #23
0
class SearchController(BaseController):

    @expose('jinja:allura:templates/search_index.html')
    @validate(dict(q=V.UnicodeString(),
                   history=V.StringBool(if_empty=False)))
    @with_trailing_slash
    def index(self, q=None, history=False, **kw):
        results = []
        count=0
        if not q:
            q = ''
        else:
            results = search.search(
                q,
                fq='is_history_b:%s' % history)
            if results: count=results.hits
        return dict(q=q, history=history, results=results or [], count=count)
Пример #24
0
class ActionSchema(CSRFSchema):
    """The :class:`~wte.views.user.ActionSchema` handles the validation of
    user action requests.
    """
    action = All(validators.UnicodeString(not_empty=True),
                 validators.OneOf(['validate', 'password', 'delete']))
    """The action to apply"""
    confirm = validators.StringBool(if_empty=False, if_missing=False)
    """Whether the user has confirmed the action"""
    user_id = ForEach(validators.Int(), if_missing=None)
    """User ids to apply the action to"""
    q = validators.UnicodeString(if_empty=None, if_missing=None)
    """Optional query parameter for the redirect"""
    status = validators.UnicodeString(if_empty=None, if_missing=None)
    """Optional status parameter for the redirect"""
    start = validators.UnicodeString(if_empty=None, if_missing=None)
    """Optional start parameter for the redirect"""
Пример #25
0
class InstanceContentsEditForm(formencode.Schema):
    allow_extra_fields = True
    allow_propose = validators.StringBool(
        not_empty=False, if_empty=False, if_missing=False)
    allow_index = validators.StringBool(
        not_empty=False, if_empty=False, if_missing=False)
    use_norms = validators.StringBool(
        not_empty=False, if_empty=False, if_missing=False)
    require_selection = validators.StringBool(
        not_empty=False, if_empty=False, if_missing=False)
    frozen = validators.StringBool(
        not_empty=False, if_empty=False, if_missing=False)
    milestones = validators.StringBool(
        not_empty=False, if_empty=False, if_missing=False)
    hide_global_categories = validators.StringBool(
        not_empty=False, if_empty=False, if_missing=False)
Пример #26
0
class SearchController(BaseController):

    @expose('jinja:allura:templates/search_index.html')
    @validate(dict(q=V.UnicodeString(),
                   history=V.StringBool(if_empty=False)))
    @with_trailing_slash
    def index(self, q=None, history=None, **kw):
        results = []
        count=0
        if not q:
            q = ''
        else:
            pids = [c.project._id] + [
                p._id for p in c.project.subprojects ]
            project_match = ' OR '.join(
                'project_id_s:%s' % pid
                for pid in pids )
            search_query = '%s AND is_history_b:%s AND (%s) AND -deleted_b:true' % (
                q, history, project_match)
            results = search.search(search_query, is_history_b=history)
            if results: count=results.hits
        return dict(q=q, history=history, results=results or [], count=count)
Пример #27
0
def lookup(dataset):
    dataset = Dataset.find(dataset)
    readonly = validators.StringBool(if_empty=False, if_missing=False)\
            .to_python(request.args.get('readonly'))
    readonly = readonly if authz.logged_in() else True
    data = request_content()
    if response_format() != 'json':
        return Response("Not implemented!", status=400)

    try:
        alias = Alias.lookup(dataset, data, request.account, readonly=readonly)
        if alias is None:
            return jsonify(
                {
                    'is_matched': False,
                    'entity': None,
                    'name': data.get('name'),
                    'dataset': dataset.name
                },
                status=404)

        if isinstance(alias, Entity):
            return jsonify(
                {
                    'is_matched': True,
                    'entity': alias,
                    'name': data.get('name'),
                    'dataset': dataset.name
                },
                status=200)

        db.session.commit()
        status = 200 if alias.is_matched else 404
        status = 418 if alias.is_invalid else status
        return jsonify(alias, status=status)
    except Invalid, inv:
        return handle_invalid(inv, index, data=data, args=[dataset.name])
Пример #28
0
class WidgetController(Controller):
    @expose('mako:moksha.templates.widget')
    @validate({
        'live': validators.StringBool(),
        'chrome': validators.StringBool(),
        'source': validators.UnicodeString(),
        'module': validators.StringBool(),
        'iframe': validators.StringBool(),
    })
    def _default(self,
                 widget,
                 chrome=False,
                 live=False,
                 source=False,
                 module=False,
                 iframe=False,
                 **kw):
        """ Display a single widget.

        :chrome: Display in a Moksha Container
        :live: Inject a socket for live widgets
        :source: Display the source code for this widget
        """
        options = {}
        options.update(kw)
        w = moksha.utils._widgets.get(widget)
        if not w:
            raise WidgetNotFound(widget)
        if (chrome and getattr(w['widget'], 'visible', True)) or source:
            tmpl_context.widget = container
            options['content'] = w['widget']
            options['content_args'] = kw
            options['title'] = w['name']
            options['id'] = widget + '_container'

            # Allow widgets to specify container options
            container_options = getattr(w['widget'], 'container_options', None)
            if container_options:
                options.update(container_options)
        else:
            tmpl_context.widget = w['widget']
        if live:
            tmpl_context.moksha_socket = moksha.utils.get_widget(
                'moksha_socket')
        if source:
            options['content'] = iframe_widget(url='/widgets/code/' + source +
                                               '?module=%s' % module,
                                               height='425px')
            options['id'] += source + '_source'
            options['view_source'] = False
        if iframe:
            options['content'] = iframe_widget(url='/widgets/' + widget + '?' +
                                               urlencode(kw),
                                               height='425px')
            options['view_source'] = False
        return dict(options=options)

    @expose('mako:moksha.templates.widget')
    @validate({
        'module': validators.StringBool(),
    })
    def code(self, widget, module=False):
        tmpl_context.widget = code_widget
        return dict(options={'widget': widget, 'module': module})
Пример #29
0
 class CheckForCheckboxSchema(Schema):
     agree = validators.StringBool(messages=self.not_empty_messages)
Пример #30
0
class RootController(BaseController, DispatchIndex, FeedController):
    def __init__(self):
        self._discuss = AppDiscussionController()

    def _check_security(self):
        require_access(c.app, 'read')

    @with_trailing_slash
    @expose()
    def index(self, **kw):
        redirect(h.really_unicode(c.app.root_page_name).encode('utf-8') + '/')

    @expose()
    def _lookup(self, pname, *remainder):
        """Instantiate a Page object, and continue dispatch there."""
        return PageController(pname), remainder

    @expose()
    def new_page(self, title):
        redirect(h.really_unicode(title).encode('utf-8') + '/')

    @with_trailing_slash
    @expose('jinja:forgewiki:templates/wiki/search.html')
    @validate(
        dict(q=validators.UnicodeString(if_empty=None),
             history=validators.StringBool(if_empty=False),
             search_comments=validators.StringBool(if_empty=False),
             project=validators.StringBool(if_empty=False)))
    def search(self,
               q=None,
               history=None,
               search_comments=None,
               project=None,
               limit=None,
               page=0,
               **kw):
        'local wiki search'
        c.search_results = W.search_results
        c.help_modal = W.help_modal
        search_params = kw
        search_params.update({
            'q':
            q or '',
            'history':
            history,
            'search_comments':
            search_comments,
            'project':
            project,
            'limit':
            limit,
            'page':
            page,
            'allowed_types': ['WikiPage', 'WikiPage Snapshot'],
        })
        return search_app(**search_params)

    @with_trailing_slash
    @expose('jinja:forgewiki:templates/wiki/browse.html')
    @validate(
        dict(sort=validators.UnicodeString(if_empty='alpha'),
             show_deleted=validators.StringBool(if_empty=False),
             page=validators.Int(if_empty=0, if_invalid=0),
             limit=validators.Int(if_empty=None, if_invalid=None)))
    def browse_pages(self,
                     sort='alpha',
                     show_deleted=False,
                     page=0,
                     limit=None,
                     **kw):
        'list of all pages in the wiki'
        c.page_list = W.page_list
        c.page_size = W.page_size
        limit, pagenum, start = g.handle_paging(limit, page, default=25)
        count = 0
        pages = []
        uv_pages = []
        criteria = dict(app_config_id=c.app.config._id)
        can_delete = has_access(c.app, 'delete')()
        show_deleted = show_deleted and can_delete
        if not can_delete:
            criteria['deleted'] = False
        q = WM.Page.query.find(criteria)
        if sort == 'alpha':
            q = q.sort('title')
        count = q.count()
        q = q.skip(start).limit(int(limit))
        for page in q:
            recent_edit = page.history().first()
            p = dict(title=page.title, url=page.url(), deleted=page.deleted)
            if recent_edit:
                p['updated'] = recent_edit.timestamp
                p['user_label'] = recent_edit.author.display_name
                p['user_name'] = recent_edit.author.username
                pages.append(p)
            else:
                if sort == 'recent':
                    uv_pages.append(p)
                else:
                    pages.append(p)
        if sort == 'recent':
            pages.sort(reverse=True, key=lambda x: (x['updated']))
            pages = pages + uv_pages
        return dict(pages=pages,
                    can_delete=can_delete,
                    show_deleted=show_deleted,
                    limit=limit,
                    count=count,
                    page=pagenum)

    @with_trailing_slash
    @expose('jinja:forgewiki:templates/wiki/browse_tags.html')
    @validate(
        dict(sort=validators.UnicodeString(if_empty='alpha'),
             page=validators.Int(if_empty=0, if_invalid=0),
             limit=validators.Int(if_empty=None, if_invalid=None)))
    def browse_tags(self, sort='alpha', page=0, limit=None, **kw):
        'list of all labels in the wiki'
        c.page_list = W.page_list
        c.page_size = W.page_size
        limit, pagenum, start = g.handle_paging(limit, page, default=25)
        count = 0
        page_tags = {}
        q = WM.Page.query.find(
            dict(app_config_id=c.app.config._id,
                 deleted=False,
                 labels={'$ne': []}))
        for page in q:
            if page.labels:
                for label in page.labels:
                    if label not in page_tags:
                        page_tags[label] = []
                    page_tags[label].append(page)
        count = len(page_tags)
        name_labels = list(page_tags)
        name_labels.sort()
        return dict(labels=page_tags,
                    limit=limit,
                    count=count,
                    page=pagenum,
                    name_labels=name_labels[start:start + limit])

    @with_trailing_slash
    @expose('jinja:forgewiki:templates/wiki/create_page.html')
    def create_wiki_page(self):
        return {}

    @with_trailing_slash
    @expose('jinja:allura:templates/markdown_syntax.html')
    def markdown_syntax(self):
        'Display a page about how to use markdown.'
        return dict(example=MARKDOWN_EXAMPLE)

    @with_trailing_slash
    @expose('jinja:allura:templates/markdown_syntax_dialog.html')
    def markdown_syntax_dialog(self):
        'Display a page about how to use markdown.'
        return dict(example=MARKDOWN_EXAMPLE)

    @expose()
    @require_post()
    @validate(W.subscribe_form)
    def subscribe(self, subscribe=None, unsubscribe=None):
        if subscribe:
            M.Mailbox.subscribe(type='direct')
        elif unsubscribe:
            M.Mailbox.unsubscribe()
        redirect(request.referer)