# Application structure

```
.
├── htdocs
│   └── luci-static
│       └── resources
│           └── view
│               └── example
│                   ├── form.js
│                   ├── htmlview.js
│                   ├── rpc-jsonmap-tablesection.js
│                   ├── rpc-jsonmap-typedsection.js
│                   └── rpc.js
├── Makefile
├── po
│   ├── templates
│   │   └── example.pot
├── README.md
└── root
    ├── etc
    │   └── uci-defaults
    │       └── 80_example
    └── usr
        └── share
            ├── luci
            │   └── menu.d
            │       └── luci-app-example.json
            └── rpcd
                ├── acl.d
                │   └── luci-app-example.json
                └── ucode
                    └── example.uc

```

Your starting point for this layout is the `applications` directory in the LuCI git repository.

A folder must be created with a name like `luci-app-appname`.

For the rest of this documentation, `appname` is `example`.

## Root files

At least one file must exist in `applications/luci-app-example` - a Makefile. This defines what license is to be applied to the code, and what packages are required for the package to be installed.

A `README.md` file is also recommended. It should provide context on what the app does, and perhaps instructions on how to test things like RPC calls.

## Javascript code

All JS code is placed under `htdocs/luci-static/resources/view/appname/`, where *appname* is the name without *luci-app-* prepended (in this case, `htdocs/luci-static-resources/view/example`).

## Menu mapping

The JSON file that maps `view/example/*` to menu items is defined in `root/usr/share/luci/menu.d`. The file is named the same as the containing folder for the app, with a **.json** extension - `luci-app-example.json`.

## ACL mapping

The JSON file that defines what APIs may be called is defined in `root/usr/share/rpcd/acl.d/`. The file is named the same as the containing folder for the app, with a **.json** extension - `luci-app-example.json`.

If ACL rights are not granted correctly, the web UI will show an error indicating "Access denied". Fix the ACL file, deploy it to the device/virtual machine, and restart `rpcd`.

## Additional files

LuCI apps do not have to have any additional files or UCI default setup. However, here's how you deal with those if needed.

### Installing additional files

Any additional files needed by this application should be placed in `root/` using the directory tree that applies. This example application needs a ucode RPCd script to be installed, so it places a file in `root/usr/share/rpcd/ucode` and called `example.uc`.

The OpenWrt packaging system will install these files automatically.

### UCI defaults

UCI defaults are documented in the [OpenWrt wiki](https://openwrt.org/docs/guide-developer/uci-defaults). They create default files in the running system's `/etc/config/` directory.

Place any defaults in the file `root/etc/uci-defaults/appname`, possibly with a number prepended to control sequencing - this example package uses `80_example` as the filename.
