If you benefit from web2py hope you feel encouraged to pay it forward by contributing back to society in whatever form you choose!

Plugin Wiki Category Widget

System for managing categories in plugin_wiki. without the need to change the models,
views or controllers of web2py, including only code to be executed in the meta-code of the wiki.

  • Runs perfectly on GAE

Ensures backward compatibility, it works independently of the core code.

I still need suggestions and help to improve the code, make a good error handling,
and any improvement that can be identified.

I would appreciate that the Code-Experts write reviews to help make this code better,
This type of widget helps those who are using plugin_wiki (cube2py) platform
to create a blog, help pages or anything that needs categories and widgets.

Demo Page

Code

Just put the code into meta-code page of plugin_wiki

"""
PageCategories and Search
Define a table and widget to manage and list page categories and search in plugin wiki
Bruno Rocha - @rochacbruno
Copy and paste this code to your own meta-code page
"""
#header
response.title = 'Your Site Title'

#Table definition
db.define_table('category',\
Field('slug',requires=(IS_SLUG(),IS_IN_DB(db,'plugin_wiki_page.slug'))),\
Field('category',requires=IS_NOT_EMPTY()),\
Field('created_by',db.auth_user,default=auth.user_id,readable=False,writable=False),\
Field('created_on','datetime',default=request.now,readable=False,writable=False),\
migrate=plugin_wiki_migrate)

#Category CleanUp
def categoryClean():
    """
    Check if a category exists for a deleted page, then delete the dead category
    """
    #populate a set with pages in db
    dbpages = set()
    [dbpages.add(item.slug) for item in db(db.plugin_wiki_page.id>0).select(db.plugin_wiki_page.slug) ]
    #populate a set with pages referenced by categories
    dbcats = set()
    [dbcats.add(item.slug) for item in db(db.category.id>0).select(db.category.slug)]
    #cleanup dead entries
    if dbcats-dbpages:
        [db(db.category.slug==page).delete() for page in dbcats-dbpages ]

def br(n=1):
    """
    >>>br(2)
    '<br /><br />'
    """
    return XML('<br />'*n)

def elink(text,url,target='_blank'):
    """
    >>>elink('Google','http://google.com')
    '<a href='http://google.com' alt='Google' target='_blank'>Google</a>'
    >>>elink('Google','http://google.com','_self')
    '<a href='http://google.com' alt='Google' target='_self'>Google</a>'
    """
    return XML("<a href='%s' alt='%s' target='%s'>%s</a>" % (url,text,target,text))


#The Widgets
class PluginWikiWidgets(PluginWikiWidgets):
    @staticmethod
    def categoryAdd(slug='{{=request.args(0)}}',\
                                  categories=None,\
                                  message='<div><br><br> Esta página foi inserida nas categorias <strong> %s </strong><br><br></div>',\
                                  showmessage='True'):
        """
        - slug: is the page slug  !! Dont Change !! keep {{=request.args(0)}} \n
        - categories: is a  comma separated list of categories (Page,Post,Tech,Food) - NO SPACE BETWEEN\n
        - message: is a message to show on page,  %s is categories list\n
        - showmessage: 'True' or 'Yes' the message is shown, Leave blank, or omit to hide the message\n
        """

        if slug and categories:
            dbcats = set()
            [dbcats.add(item.category) for item in db(db.category.slug==slug).select(db.category.category)]

            cats = set(categories.split(','))

            if dbcats-cats:
                [db((db.category.category==cat)&(db.category.slug==slug)).delete() for cat in dbcats-cats]

            if cats-dbcats:
                [db.category.insert(slug=slug,category=cat) for cat in cats-dbcats]

        if len(showmessage) > 0 :
            #return XML(message % categories) 
            return XML(message % SPAN(*[A('%s ' % cat ,_href=URL(r=request,f='page',args=['categoryitems',cat])) for cat in cats]))
        else:
            return '<br>'

    @staticmethod
    def categoryList(searchpage='categoryitems'):
        """
        - searchpage is the name of the page that will show the posts for a category
        """
        categoryClean()
        dbcategories = db(db.category.id>0).select()
        if dbcategories:
            #distinct categories, to run on GAE
            categories = set()
            [categories.add(cat.category) for cat in dbcategories]
            categories = sorted(categories)

            return UL(*[LI(*[A(cat.capitalize(),_href=URL(r=request,f='page',args=[searchpage,cat]))])\
                                for cat in categories])
        else:
            return ''

    @staticmethod
    def categoryListItems(category='{{=request.args(1)}}',\
                                            nfmessage='<div><br><br>Nothing found to the category <strong> %s </strong><br><br></div>'):
        """
        - category is the category name parameter, {{=request.args(1)}} takes first argument passed to the page
        """
        items = (db(db.category.category==category).select()).sort(lambda row:row.slug)
        if items:
            return UL(*[LI(*[A(XML(db(db.plugin_wiki_page.slug==item.slug)\
                                            .select(db.plugin_wiki_page.title)[0].title),\
                                         _href=URL(request.application,'plugin_wiki','page',args=[item.slug,]))])\
                                for item in items])
        else:
           return nfmessage % category

    @staticmethod
    def searchPages(string=None,nfmessage='Nothing found with %s'):
        """
        string: string to be found
        """
        found = set()

        string = request.vars.search

        if string:
            #search in slug
            pages = db(db.plugin_wiki_page.id>0).select(db.plugin_wiki_page.slug)
            for page in pages:
                if page.slug.find(string) > -1:
                    found.add(page.slug)

            #search in page body
            pages = db(db.plugin_wiki_page.id>0).select(db.plugin_wiki_page.slug,db.plugin_wiki_page.body)
            for page in pages:
                if page.body.find(string) > -1:
                    found.add(page.slug)

            #search in page body
            pages = db(db.plugin_wiki_page.id>0).select(db.plugin_wiki_page.slug,db.plugin_wiki_page.title)
            for page in pages:
                if page.title.find(string) > -1:
                    found.add(page.slug)


            if found:
                cleanfound = set()
                for row in found:
                    if row[:4]!='meta':
                        cleanfound.add(row)

                return UL(*[LI(*[A(XML(db(db.plugin_wiki_page.slug==row)\
                                            .select(db.plugin_wiki_page.title)[0].title),\
                                         _href=URL(request.application,'plugin_wiki','page',args=[row,]))])\
                                for row in cleanfound])
            #r=request,f='page'
            else:
                return nfmessage % string

        else:
            return ''

    @staticmethod
    def showHideSidebar(showtext='[ Exibir Barra Lateral ]',hidetext='[ Esconder Barra Lateral ]'):
        return "<a id='hide' class='showhide'>%(hide)s</a><a id='show' class='showhide'>%(show)s</a>"  % {'hide':hidetext,'show':showtext}

    @staticmethod
    def nextPrevPage(slug='{{=request.args(0)}}',first='000',last='999'):
        """
        #########################################################################
        #THAT WORKS ONLY IF YOU NAME YOUR PAGES AS something-000,something-001...
        #this uses the last 3 elements after '-' in the page slug
        #########################################################################
        - slug is the actual page slug
        - first defines the page that is the first in the sequence
        - last is the same
        """
        pagenumber = slug.split('-')[-1]
        e = False
        try:
            nextpage = '%03d' % (int(pagenumber)+1)
            previouspage = '%03d' % (int(pagenumber)-1)
        except Exception, e:
            nextpage= ''
            previouspage = ''
            pass

        pages = []
        prepend = '-'.join(slug.split('-')[:-1])+'-'

        if not pagenumber==first and not previouspage==first:
            pages.append({'text':'<< Voltar ','link':prepend+previouspage})

        if not pagenumber==first:
            pages.append({'text':' | Início | ','link':prepend+first})

        if not pagenumber==last and not nextpage==last:
            pages.append({'text':'Continuar >> ','link':prepend+nextpage})

        if pages:
            return XML('[ %s ]' % SPAN(*[A('%s ' % page['text'] ,_href=URL(r=request,f='page',args=[page['link'],])) for page in pages]))

The usage

You will be able to add the widgets via widget-builder

  • categoryAdd Manage categories on each page, you can set how many categories you need per page
  • categoryList shows a distinct list of categories, with a link to a page that shows all pages under a category ( this is the widget used in meta-sidebar )
  • categoryListItems Shows a list of pages under a category that is passed to the page parameter

How to Add a Category to a page

  • slug: is the page slug, leave it unchanged to catch the actual page name
  • categories is a comma separeted list of categories, case-sensitive, no black space allowed
  • message: is the message shown as return, default is a list of categories for the page
  • showmessage: flagto show or not the message

    ``  
    name: categoryAdd
    slug: {{=request.args(0)}}
    categories: category1,category2,categoryN  
    message: <div><br><br> This page is under <strong> %s </strong> category(ies)<br><br></div>
    showmessage: True
    ``:widget
    

How to List Categories

  • searchpage: is the name of the page that link in each category listed will follow

    ``  
    name: categoryList  
    searchpage: categoryitems  
    ``:widget
    

How to List Category Items ( to be used as a search page)

  • category: catch the category name from arg passed to page
  • nfmessage: the message shown when nothing is found

    ``  
    name: categoryListItems
    category: {{=request.args(1)}}
    nfmessage: <div><br><br>Nothing Found under the category <strong> %s </strong><br><br></div>
    ``:widget
    

How to add Ajax Search and category list to meta-sidebar (or anywhere)

``
<script> 
 $(document).ready(function(){
     //translates auth.navbar
     $('.auth_navbar').html('[ <a href="/init/default/user/login">Efetuar login</a> | <a href="/init/default/user/register">Cadastre-se</a> ]')
   // Search function
   $('#search').keyup(function(){ 
    ajax("{{=URL(r=request, c='plugin_wiki',f='page.load/searchpages')}}",['search'],'target'); 
        return false; 
    }); 
 });
</script>
 <br>
<h2>Busca</h2>
<form>
<input id='search' name='search'>
</form>
<div id='target' name='target'></div>
<br />
``:template

## Categorias
``
name: categoryList
searchpage: categoryitems
``:widget

Create the page that responds to the search

  • searchpages

``

``
 name: searchPages
string: {{=request.args(1)}}
nfmessage: Não encontrados com a palavra (%s)
``:widget

TO-DO (Help Needed):

  • remove blank spaces from category list
  • make category list, case unsensitive
  • Counter to show on categoryList
  • Create a Modal Box with JavaScript, to add categories

Related slices

Comments (0)


Hosting graciously provided by:
Python Anywhere