St.footer()

Hello Fallas,

since I was amazed that my footer looks so neat,
I have been thinking about how to make it more general, so that others may benefit from it.
Also i wanted to make it reusable and easy to configure.
Therefore I have come up with the following code (python > 3.7):

import streamlit as st
from htbuilder import HtmlElement, div, ul, li, br, hr, a, p, img, styles, classes, fonts
from htbuilder.units import percent, px
from htbuilder.funcs import rgba, rgb


def image(src_as_string, **style):
    return img(src=src_as_string, style=styles(**style))


def link(link, text, **style):
    return a(_href=link, _target="_blank", style=styles(**style))(text)


def layout(*args):

    style = """
    <style>
      # MainMenu {visibility: hidden;}
      footer {visibility: hidden;}
     .stApp { bottom: 105px; }
    </style>
    """

    style_div = styles(
        position="fixed",
        left=0,
        bottom=0,
        margin=px(0, 0, 0, 0),
        width=percent(100),
        color="black",
        text_align="center",
        height="auto",
        opacity=1
    )

    style_hr = styles(
        display="block",
        margin=px(8, 8, "auto", "auto"),
        border_style="inset",
        border_width=px(2)
    )

    body = p()
    foot = div(
        style=style_div
    )(
        hr(
            style=style_hr
        ),
        body
    )

    st.markdown(style, unsafe_allow_html=True)

    for arg in args:
        if isinstance(arg, str):
            body(arg)

        elif isinstance(arg, HtmlElement):
            body(arg)

    st.markdown(str(foot), unsafe_allow_html=True)


def footer():
    myargs = [
        "Made in ",
        image('https://avatars3.githubusercontent.com/u/45109972?s=400&v=4',
              width=px(25), height=px(25)),
        " with ❤️ by ",
        link("https://twitter.com/ChristianKlose3", "@ChristianKlose3"),
        br(),
        link("https://buymeacoffee.com/chrischross", image('https://i.imgur.com/thJhzOO.png')),
    ]
    layout(*myargs)


if __name__ == "__main__":
    footer()

You can easily adjust the footer to your needs. You just have to pass the args in the appropriate order. Currently there are four types of args possible:

  1. Text simply with " "
  2. Images with source, styles
  3. links with href, text and styles
  4. HtmlElement (e.g. br() for line break)

In addition (without guarantee) all four components can be nested arbitrarily.
For the general layout of the footer you can adjust style_div and stlye_p respectively.

This is how it looks like:

Ofc, it is not perfect, but I guess a good start.
For all those who want it, feel free to reuse it and improve it.
Also it would be nice, if you guys @streamlit could include it in the library
so that I can use it easier next time too :grin:. Maybe st.footer() would be nice?

Cheers
Chris

5 Likes

Nice! We’ve been considering adding something like that to Streamlit. Will bookmark this for when we have another discussion on this topic

It’s also cool that you’re using my htbuilder library :smiley:

3 Likes

Great job on the footer Chris! :slight_smile:

2 Likes

:slight_smile: It is only possible due to the fact that i am

Standing on the shoulders of giants

htbuilder is a great library, once I understood how it works.
What i did not see was general style Class for the document so I had to do it with html.

<style>
  # MainMenu {visibility: hidden;}
  footer {visibility: hidden;}
</style>

or is there @thiago ?

Main props to @Charly_Wargnier for the idea of the footer!

2 Likes

Hey @chris_klose, I tried executing the code but stuck at this error.

ImportError: cannot import name ‘div’

Traceback:

File "/usr/local/lib/python3.6/dist-packages/streamlit/script_runner.py", line 324, in _run_script
    exec(code, module.__dict__)File "/content/app.py", line 2, in <module>
    from htbuilder import HtmlElement, div, ul, li, br, hr, a, p, img, styles, classes, fonts

did you install htbuilder ?
pip install htbuilder

yes, I did install pip install htbuilder

Error:


ImportError Traceback (most recent call last)
in ()
----> 1 from htbuilder import div

ImportError: cannot import name ‘div’


Not currently.

Although it should be easy to add that to htbuilder, with an API like:

style({
  '.foo > bar': styles(color='red', visibility='hidden'),
  '#baz': styles(position='absolute', top=px(10)),
})

If I have some time later this week I’ll look into this!

1 Like

You should be able to replace p()() with just p()

1 Like

Would you please provide a SS of how this footer would look like ?

Ofc, here yo go.

You can easily adjust the footer to your needs. You just have to pass the args in the appropriate order. Currently there are four types of args possible:

  1. Text simply with " "
  2. Images with source, styles
  3. links with href, text and styles
  4. HtmlElement (e.g. br() for line break)

In addition (without guarantee) all four components can be nested arbitrarily.
For the general layout of the footer you can adjust style_div and stlye_p respectively.

myargs = [
    "Made in ",
    image('https://avatars3.githubusercontent.com/u/45109972?s=400&v=4',
          width=px(25), height=px(25)),
    " with ❤️ by ",
    link("https://twitter.com/ChristianKlose3", "@ChristianKlose3"),
    br(),
    link("https://buymeacoffee.com/chrischross", image('https://i.imgur.com/thJhzOO.png')),
]
1 Like