Best Practices
Using Components
As your configuration grows, you might want to improve its structure by factoring out pieces into reusable components.
In Ewwii's Nbcl-based configuration system, you can define wrapper functions that return widgets and accept a children parameter (or any parameter that you prefer), just like built-in widgets such as box() or button().
Here's an example of a custom container that adds a label before its children:
component LabeledContainer () {
Box {
class = "container"
Label {
text = self.id
}
self.children
}
}You can call it like this:
LabeledContainer "foo" {
Button {
onclick = "notify-send hey ho"
label = "Click me"
}
}Window ID
In some cases you may want to use the same window configuration for multiple widgets, e.g. for multiple windows. This is where arguments and ids come in.
Firstly let us start off with ids. An id can be specified in the open command
with --id, by default the id will be set to the name of the window
configuration. These ids allow you to spawn multiple of the same windows. So
for example you can do:
ewwii open my_bar --screen 0 --id primary
ewwii open my_bar --screen 1 --id secondaryGenerating a list of widgets from array using for
If you want to display a list of values, you can use the for-Element to fill a container with a list of elements generated from a JSON-array.
let my_array = [1, 2, 3];
# Inside your widget, you can do this
Box {
for entry in my_array {
Button {
onclick = "notify-send 'click' 'button ${entry}'",
label = entry.to_string()
}
}
}This can be useful in many situations, for example when generating a workspace list from an array representation of your workspaces.
Splitting up your configuration
As time passes, your configuration might grow larger and larger. Luckily, you can easily split up your configuration into multiple files!
There are two options to achieve this:
Using import/export
# in ./foo/baz.nbcl
## Note: all functions and variables
## at the top level are automatically exported.
fn greet() { return "Greetings!" }
let PI = 3.14159
# in ./ewwii.nbcl
import "foo/baz.nbcl" as example;
print(example.greet()); # Greetings!
print(example.PI); # 3.14159A nbcl file may import the contents of any other rhai file that they export. For this, make use of the import directive. However, a slight limitation is that import "eg.nbcl" as example only imports functions and variables under the example namespace. To import a component, you would have to use this syntax:
# in ./example.nbcl
component ExampleCmp () {
# implementation omitted ...
}
# in ./main.nbcl
import "example.nbcl" as example { ExampleCmp }
ExampleCmp {
# All the functions and variables are
# imported under the `example` variable,
# and components are imported directly as-is.
}Using a separate ewwii configuration directory
If you want to separate different widgets even further, you can create a new ewwii config folder anywhere else.
Then, you can tell ewwii to use that configuration directory by passing every command the --config /path/to/your/config/dir flag.
Make sure to actually include this in all your ewwii calls, including ewwii kill, eww logs, etc.
This launches a separate instance of the ewwii daemon that has separate logs and state from your main ewwii configuration.
ewwii --config "/path/to/your/config/dir"