[luci] Adding a page to luci

Frank Parker mr.frank.parker at gmail.com
Thu Jan 10 17:49:47 CET 2013


Andrew, wow.  Thanks for the deep technical detail.  Unfortunately, it's
about a mile over my head.  Still learning lua/luci.  However, this gives
me lots of information to research and absorb.  Thanks!


On Tue, Jan 8, 2013 at 6:34 PM, Andrew Peebles
<peebles at cortina-systems.com>wrote:

>  On 01/08/2013 05:19 PM, Nguyễn Hồng Quân wrote:
>
> Hello,
>
> You can see my mod as a reference https://github.com/hongquan/KikiAuth
> I started from this doc:
> http://luci.subsignal.org/trac/wiki/Documentation/ModulesHowTo
> then http://luci.subsignal.org/trac/wiki/Documentation/CBI
> ...
>
> Hope you see it helpful.
>
> ***********************************************
> * Nguyễn Hồng Quân                            *
> * Y!M: ng_hquan_vn                            *
> * Identi.ca: hongquan                         *
> ***********************************************
>
>
> 2013/1/9 Frank Parker <mr.frank.parker at gmail.com>
>
>> If someone here is willing to walk me through the steps required to
>> customize my luci interface, I would be happy to document it.  Seems useful
>> since this is a common newbie question.
>>
>>  My mod would be adding a single page with a single textbox that gets
>> saved to /etc/config/myapp
>>
>>  So for example, under System I would like to add a new tab called
>> "MyApp" that displays a page with a single textbox.  The value in the
>> textbox gets saved to /etc/config/myapp.  That's it.
>>
>>  For bonus points, I also need a single button on the same page that
>> will run a local script when clicked.
>>
>>  On OpenWrt Backfire 10.03.1, I am hunting around in /usr/lib/lua/luci/*
>> but not having much luck.
>>
>>  Anyone?
>>
>> _______________________________________________
>> luci mailing list
>> luci at lists.subsignal.org
>> https://lists.subsignal.org/mailman/listinfo/luci
>>
>>
>
>
> _______________________________________________
> luci mailing listluci at lists.subsignal.orghttps://lists.subsignal.org/mailman/listinfo/luci
>
>  I find that it easier, and more portable, to create a new package.  The
> instructions below do not include code/support for generating i18n language
> files, but that can be wedged in.
>
> First create a directory for the new package.  Easiest is:
>
>   mkdir -p package/luci-app-myapp/files/controller
>   mkdir -p package/luci-app-myapp/files/model/cbi
>   mkdir -p package/luci-app-myapp/files/uci-defaults
>
> This example will assume there is already a package called "myapp", which
> installs its own /etc/init.d/myapp and /etc/config/myapp.  That is the
> typical break-out, so that myapp can be used in a system even without a
> GUI.   The package/luci-app-myapp/Makefile would look like:
>
> include $(TOPDIR)/rules.mk
>
> PKG_NAME:=luci-app-myapp
> PKG_VERSION:=1
> PKG_RELEASE:=1
>
> include $(INCLUDE_DIR)/package.mk
>
> define Package/luci-app-myapp
>   SECTION:=luci
>   CATEGORY:=LuCI
>   SUBMENU:=3. Applications
>   TITLE:=GUI for myapp package
>   PKGARCH:=all
>   DEPENDS:=+myapp
> endef
>
> define Build/Configure
> endef
>
> define Build/Compile
> endef
>
> define Package/luci-app-myapp/install
>         $(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller
>         $(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi
>         $(INSTALL_DIR) $(1)/etc/uci-defaults
>         $(CP) ./files/controller/myapp.lua \
>                 $(1)/usr/lib/lua/luci/controller/
>         $(CP) ./files/model/cbi/myapp.lua \
>                 $(1)/usr/lib/lua/luci/model/cbi/
>         $(CP) ./files/uci-defaults/luci-app-myapp \
>                 $(1)/etc/uci-defaults/
> endef
>
> define Package/luci-app-myapp/postinst
> #!/bin/sh
> [ -n "$${IPKG_INSTROOT}" ] || {
>         if [ -f /etc/uci-defaults/luci-app-myapp ]; then
>             ( . /etc/uci-defaults/luci-app-myapp ) && rm -f
> /etc/uci-defaults/luci-app-myapp
>         fi
> }
> endef
>
> $(eval $(call BuildPackage,luci-app-myapp))
>
> Some interesting points above: DEPENDS makes sure that "mayapp" is
> installed and selected for build when this package is selected.  In the
> install macro, the three pertinent files (the controller, the model and the
> uci-defaults will get installed into the correct LuCI runtime hierarchy.
> The postinst thing will run the luci-app-myapp script on the target at
> installation time.  That script should look like this:
>
> #!/bin/sh
>
> uci -q batch <<-EOF >/dev/null
>         delete ucitrack. at myapp[-1]
>         add ucitrack myapp
>         set ucitrack. at myapp[-1].init=myapp
>         commit ucitrack
> EOF
>
> rm -f /tmp/luci-indexcache
> exit 0
>
> This is the magic that ends up calling /etc/init.d/myapp when you click on
> the Save&Apply button in LuCI.
>
> Ok, so the controller (controller/myapp.lua) would look like this:
>
> module("luci.controller.myapp", package.seeall)
>
> function index()
>    -- dont show unless myapp package is installed
>    --
>    if not nixio.fs.access("/etc/config/myapp") then
>       return
>    end
>
>    local page
>
>    -- install this page into the hierarchy under admin -> services
>    page = entry({"admin", "services", "myapp"},
>                 cbi("myapp"),
>                 _("My Application"))
>
>    -- the i18n file's base name
>    page.i18n = "myapp"
>    page.dependent = true
> end
>
> And the model (model/cbi/myapp.lua) would look like:
>
> -- "myapp" here refers to the name of the file in /etc/config
> --
> m = Map("myapp", translate("My Application"),
>         translate("Some optional additional text..."))
>
> -- this refers to a section in the config file.
> --
> s = m:section( NamedSection, "configuration", "myapp",
> translate("Settings"))
>
> -- and then the options in that section
> --
> o = s:option( Value, "field", translate( "Field" ))
>
> -- we're done!
> --
> return m
>
> The way this model is written expects a /etc/config/myapp file that looks
> like this:
>
> config myapp configuration
>   option field 'some_initial_value'
>
> At this point you should be able to "make menuconfig", select your new
> package, and "make".  I typed this entirely in my email client without any
> actual verification, so there may be minor syntax errors, etc, and I
> apologize for that in advance.
>
> As for the bonus question about the button; as I know how to do things,
> that is a fairly advanced topic.  Its a little rough mixing cbi models and
> gui stuff that is not part of the /etc/config file in question.  cbi models
> are fantastic if all you want to do is provide gui for config.  But, it is
> possible.  It involves creating another option of type DummyValue and
> creating a custom template for it.  The template goes into
> view/myapp/myview.htm.  This template can paint any picture it wants.  You
> can place a button with an onclick javascript call or an href that calls a
> function defined in the controller.  You can even use ajax to get json back
> from the call.  I'll outline this from memory, so it might also be a bit
> buggy, but maybe enough to set you down the right path:
>
> In the controller, add a new entry that looks like this (in the index()
> function):
>
>    entry({"admin", "services", "myapp", "func"},
>          call("action_func")).leaf = true
>
> Now, in the same file, add a new function:
>
> function action_func()
>     -- obtain any arguments passed (form entries or ajax data)
>     local field1 = luci.http.formvalue("field1")
>     -- do something, more interesting ...
>     -- then return json
>     luci.http.prepare_content("application/json")
>     luci.http.write_json({return_value = field1})
> end
>
> You can define as many of these entry points as you want.  Now, in the
> model file, add another option, something like this:
>
>     o = s:option(DummyValue, "_val", translate("Title"))
>     o.template = "myapp/myview.htm"  -- is the html making up the gui
>
> I *think* this is all you need.  You then need to create the template (and
> fix your Makefile to install it in the proper place).  It might look like:
>
> <button onclick="doit();">My Button</button>
> <script>
> function doit() {
>   $.ajax({
>     url: '<%=luci.dispatcher.build_url("admin", "services", "myapp",
> "func")%>',
>     data: {field1: 'it works!'},
>     dataType: 'json',
>     success: function(json) {
>         alert( json.return_value);
>     },
>     error: function(e, m) {
>         alert("Crap, spoke too soon: " + m);
>     }
>   });
> }
> </script>
>
> Of course, that assumes you have jQuery installed and available (which you
> can do here in this template).  Or you can use the xhr.js that is already
> available in LuCI themes.  But you get the idea, I hope.
>
> That has some chance of working.  If its horribly broken and you can't
> untangle it, lemme know and I'll actually try it and debug it for you.
>
> a
>
>
> _______________________________________________
> luci mailing list
> luci at lists.subsignal.org
> https://lists.subsignal.org/mailman/listinfo/luci
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.subsignal.org/pipermail/luci/attachments/20130110/35a1815f/attachment-0001.html>


More information about the luci mailing list