Skip to content

tkeech1/streamweb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Streamweb

Streamweb is a template for creating a blog or portfolio site based on Steamlit. Streamweb allows you to combine multiple Streamlit dashboards into a single web site. It also enables interactive blog posts that allow users to modify content using Streamlit widgets. Issues and PRs for improvements are welcome!

Step 1: Clone the repo

git clone https://github.com/tkeech1/streamweb
cd streamweb

Step 2: Run Streamlit

cd streamweb
streamlit run layout_clean_sidebar.py

Step 3: Browse to http://localhost:8501/

Documentation

Layouts

The streamweb directory contains the entry point to the application. An application can have multiple layouts, although only one can be enabled at a time. The layout determines how content will be displayed on the main screen. A layout uses standard Streamlit syntax (st.write(), st.markdown(), st.title(), etc.) to build the display.

Layouts are responsible for loading and displaying content. Content is stored separately (for the most part) from the layout although there are some conventions to which content must conform. These are covered in the Content section.

Changing the layout

To change to a different layout, use a different layout file:

streamlit run layout_clean_no_sidebar.py
Creating a new layout

To create a new layout, copy one of the existing layouts and add it to the streamweb directory. Then, run streamlit using the new layout as shown above.

streamlit run layout_my_new_layout.py

Content

Streamweb was built to mimic static site generators such as Hugo. Content is stored in Python modules which are stored in Python packages under the streamweb directory on the filesystem; a database isn't necessary. In the examples, content is separated into two types, static content and dynamic content. Static content, stored in the static package, is intended for content that doesn't change frequently such as an "About Me" page. Dynamic content, stored in the dynamic package is intended for content that's updated frequently such as blog posts. Users can create new Python packages containing content under the streamweb directory and load them as described below.

Site Setup

To create a site, create a StreamwebSite object in the layout as shown in the example:

sws: StreamwebSite = StreamwebSite(
    site_config.website_id,
    site_config.website_title,
    site_config.website_description,
    site_config.website_author,
    site_config.website_url,
    site_config.website_language,
    site_config.environment,
)

environment is a flag that indicates whether or not to dynamically reload content modules. If environment=='prd', the dynamic content reloading is disabled. The StreamwebSite object provides a few helper methods to streamline building a site.

Content Loading

In a layout, content modules are loaded by calling the sws.load_content('package_name') function. This function returns a list of Python modules which can be iterated over and displayed in the layout.

In the example layouts, the content packages static and dynamic packages are loaded by the layout in the following lines.

static_content = load_content("static")
dynamic_content = load_content("dynamic")

All content modules are cached using Streamlit's st.cache() decorator and are dynamically reloaded if the module changes. Dynamic reloading makes it easy to develop new content without having to restart Streamlit after each edit. Dynamic module reloading can be disabled by running Streamlit as shown below:

streamlit run layouts/clean_no_sidebar.py -- prd
Creating New Content

A new content module can be created by copying and existing content module and renaming it. You need to restart Streamlit to load new content modules.

Creating New Content Packages

To create a new content package, create a new directory under the streamweb directory. Create an __init__.py file inside the directory so Python knows it's a package. Then, create new content modules as noted above.

To load the content inside a layout:

my_new_content = sws.load_content("mynewpackage")
Displaying Content

Once you've loaded module content, you can display the content by calling the render() function of the content module.

my_new_content[i].render()

To display a list of button links to the content:

button_click_flags = sws.create_buttons("dynamic", st)

This creates a list, button_click_flags, of bools that indicate which button was clicked. Unfortunately, Streamlit doesn't appear to support getting the key of the button that was clicked so this is a workaround.

There are two helper methods for displaying content, sws.render_content_by_click and sws.render_content_by_key. Below is an example of rendering content based on a button click.

if any(button_click_flags):
    sws.render_content_by_click(
        content_name="static",
        location=st,
        button_click=static_content_button_click,
    )

Here is an example of rendering content based on an content key.

if content_id:
    sws.render_content_by_key("dynamic", location=st, content_key=content_id)
Content Format

Streamweb expects all content modules to contain the following attributes and functions:

Attributes
short_title: A short title for the content (usually displayed in a link or button)
long_title: A long title for the content (usually displayed as a page title)
content_date: A Python date used for sorting content. By default content is sorted in date descending order (most recent posts appear at the top)
key: A unique key used in URLs
Functions
render(): Function containing standard Python code and Streamlit syntax for building the display

There are several examples of dynamic and static content included in this repo.

TODO

  • UI tests
  • Sphinx docs

About

A basic blog/portfolio web site template based on Streamlit.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages