['Development'] ['Development/Plugins'] = Webui Examples = '''Tested and developed on deluge-svn/Deluge 1.1''' [[PageOutline(1-3,index,inline)]] == Adding a page to the webui == === Intro === Webui templates are dumb, they get passed data from python, and can't call uiclient api's directly. They are there to format the data, not to execute logic. Template language: http://webpy.org/templetor == Flow of the data == ''Disclaimer, MVC is a highly abused therm, and i'm abusing it here.'' {{{ [core-plugin],deluged->uiclient->webui,[webui-plugin] -> data passed as arguments to template. ('Model' ) ('controller' ) ('view') }}} == Example : a df page in webui == This example assumes you have deluge svn checked out to "~/src/deluge" And that your plugin-development-directory is "~/prj/deluge/plugins" This plugin will add a page to deluge that display the output of "df -h" to a page in the webui. === Create a new plugin === {{{ cd ~/prj/deluge/plugins python ~/src/deluge/deluge/scripts/create_plugin.py --name Df --basepath . --author-name "My Name" --author-email "deluge@example.com" }}} * Restart deluge(d) and enable the plugin in the gtk-ui. === Add a core method. === Add this method to ~/prj/deluge/plugins/Df/df/core.py {{{ #!python def export_get_df(self): "returns the result of 'df -h' as a string" import commands return commands.getoutput('df -h') }}} === Test the new core-plugin method. === create ~/prj/deluge/plugins/df/Df/test.py ; Contents: {{{ #!python from deluge.ui.client import sclient sclient.set_core_uri() print sclient.df_get_df() #export method is prefixed by plugin-name. }}} Terminal: {{{ cd ~/prj/deluge/plugins/Df/df killall deluged & deluged && python test.py }}} Fix any errors until the test outputs the desired result. === Add the template === ~/prj/deluge/plugins/Df/df/templates/df.html {{{ $def with (df_result)

df -h

$df_result
}}} === Webui plugin === Edit ~/prj/deluge/plugins/Df/df/webui.py and add this above ConfigForm Note that api.render.df automatically maps to df.html , because of the call to api.render.register_template_path (see http://webpy.org/) {{{ #!python template_dir = os.path.join(os.path.dirname(__file__),"template") class df_page(): #@api.deco.deluge_page #requires login, see page_decorators.py for more decorators, @api.deco.deluge_page_noauth #<-- this is easier for testing until i implement persistent sessions. def GET(self, args): df_result = sclient.df_get_df() return api.render.df(df_result) #push data to templates/df.html class WebUI(object): #replace/remove the old WebUI class def __init__(self, plugin_api, plugin_name): log.debug("Df plugin initalized..") self.plugin = plugin_api def enable(self): api.config_page_manager.register('plugins','df',ConfigForm) api.render.register_template_path(template_dir) #<--added api.page_manager.register_page('/df', df_page) #<--added def disable(self): api.config_page_manager.unregister('df') api.render.unregister_template_path(template_dir) #<--added api.page_manager.unregister_page('/df') #<--added }}} === Test webui page === {{{ killall deluge & deluge -u web & }}} Read the output to the console, there could be some errors there. visit http://localhost:8112/df Execute test until there are no more errors, and the page displays the desired result. === Add to top menu === We added a page, but the user can't navigate to it, let's fix that : Add 2 lines for register/unregister of the menu-items. {{{ #!python def enable(self): api.config_page_manager.register('plugins','df',ConfigForm) api.render.register_template_path(template_dir) #<--added api.page_manager.register_page('/df', df_page) #<--added api.menu_manager.register_admin_page("df", _("Disk usage"), "/df") #<--top menu def disable(self): api.config_page_manager.unregister('df') api.render.unregister_template_path(template_dir) #<--added api.page_manager.unregister_page('/df') #<--added api.menu_manager.unregister_admin_page("df") #<--top menu }}} === Pretty template === We're allmost ready, but the current template doesn't look right. Adding a header/footer and menu to the template: {{{ $def with (df_result) $:render.header(_("Disk usage"), 'df') $:render.admin_toolbar('df')

Disk usage (df -h)

$df_result
'
$:render.footer() }}} == Notes/Future == * (template_dir/path) is a convention, it will be automagic somewhere in the future. * all webui unregister_* methods will be renamed to deregister_*