Make you own Widget

Swole is bundled with some general-use Widget. But sometimes you need more than that !

To fit your specific needs, you can create a custom Widget.

Let’s see together in this guide how to create a custom Widget. We will create a Widget making two buttons.

Step 1 : sub-class Widget

Let’s create a sub-class of Widget :

from swole.widgets import Widget

class TwoButtons(Widget):
    pass

Let’s change the constructor to take two strings (the text of each button) :

class TwoButtons(Widget):
    def __init__(self, text1="Button 1", text2="Button 2", **kwargs):
        super().__init__(**kwargs)
        self.text1 = text1
        self.text2 = text2

Step 2 : create HTML

Now we have to overwrite the method html(), where the HTML of the Widget is defined :

from dominate.tags import button, div

class TwoButtons(Widget):
    def html(self):
        attributes = {"id": self.id}        # Best practice : Always add the ID of the Widget
        self.add_css_class(attributes)      # Method from super to add custom CSS classes

        d = div(**attributes)
        with d:
            button(self.text1)
            button(self.text2)
        return d

Warning

You should use the dominate library to create the HTML object returned by html().

Step 3 : define setter and getter

setter and getter are methods used by Javascript for the AJAX requests. It’s the gateway between Python and Javascript.

In our case it’s simple :

class TwoButtons(Widget):
    def get(self):
        return [self.text1, self.text2]

    def set(self, x):
        self.text1 = x[0]
        self.text2 = x[1]

Step 4 : define AJAX (optional)

Optionally, your Widget can also overwrite the method ajax(). This method is used to retrieve AJAX requests linked to this Widget. It should return a Ajax object.

You can refer the implementation of Button for an example.

Step 5 : use your widget

You’re all done ! Now you just have to use your Widget is one of your web application !

TwoButtons(text2="My 2 buttons")

if __name__ == "__main__":
    Application().serve()