JavaScript support

Yattag does not modify nor even analyze added js sources. You provide them as strings and these are rendered in /html/head/script section. Each addition places the content in separate <script> section.

Of course there is also possibility to link external js source file.

Internal JS

Appending js to Yawrap or Navrap instances can be done appending string-code to Class

Note

Yawrap has a class-level atribute being a list named js. It is supposed to contain JavaScript code as strings. Similary as with CSS, you can derive from Yawrap class and also define the class-level JS that will be inherited by its subclasses unless you override it.

Using jQuery

It’s an adaptation of following example: https://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_fadetoggle


from yawrap import Yawrap, ExternalJs, EmbedCss, EmbedJs, BODY_END


class MyPageTemplate(Yawrap):
    resources = [
        ExternalJs("https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"),
        EmbedCss("""\
        body {
            padding: 12px;
            font-family: helvetica, sans-serif;
            font-size: 14px;
        }
        .box {
            display: inline-block;
            height: 80px;
            margin: 8px;
            padding: 8px;
            width: 80px;
        }"""),
        EmbedJs("""\
        $("button").click(function(){
            $("#red-box").fadeToggle();
            $("#green-box").fadeToggle("slow");
            $("#blue-box").fadeToggle(3000);
        });""", placement=BODY_END),
    ]

    def _create_box(self, name, color):
        style = "background-color:{};".format(color)
        with self.tag('div', id=name, klass="box", style=style):
            self.text(name)

    def fill_with_content(self):
        with self.tag("h2"):
            self.text("Demonstrate a simple JavaScript.")

        with self.tag('p'):
            self.text("fadeToggle() operating with different speed parameters.")

        with self.tag('button'):
            self.text("Click to fade in/out boxes")

        with self.tag("div"):
            self._create_box('red-box', "red")
            self._create_box('green-box', "#0f0")
            self._create_box('blue-box', "#0a1cf0")


def create_page(output_file_path):
    doc = MyPageTemplate(output_file_path, "Name of the page")
    doc.fill_with_content()
    doc.render()

# that's it

Will create a page as below. Note that the placement=BODY_END in EmbedJs call caused the script to be placed at the end. Withouth that argument it would get into head section.

That looks like this:

Sharing scripts and styles across multiple pages

Similar effect as above but with reusable java scripts and CSS can be obtained by defining them as class level attributes like this:



from yawrap import LinkCss, LinkJs


class MyPage(MyPageTemplate):
    resources = [
        ExternalJs("https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"),
        LinkCss("""\
        body {
            padding: 12px;
            font-family: helvetica, sans-serif;
            font-size: 14px;
        }
        .box {
            display: inline-block;
            height: 80px;
            margin: 8px;
            padding: 8px;
            width: 80px;
        }""", file_name="common_linked.css"),
        LinkJs("""\
        $("button").click(function(){
            $("#red-box").fadeToggle();
            $("#green-box").fadeToggle("slow");
            $("#blue-box").fadeToggle(3000);
        });
        """, placement=BODY_END, file_name="common_linked.js"),
    ]

    # uses methods inherited from MyPageTemplate defined above


def create_page_with_linked_resources(output_file_path):
    doc = MyPage(output_file_path)
    doc.fill_with_content()
    doc.render()


Which produces the page:

..and the script resources/common_linked.js:

..and the style resources/common_linked.css: