by Audrey M. Roy Greenfeld | Sun, Feb 9, 2025
Now that I have a lot of notebooks, it would be nice to have a more compact index page. I want to see more of my posts from mobile all at once. I'm going to prototype it in Tailwind.
from datetime import datetime from execnb.nbio import read_nb from fastcore.utils import * from fasthtml.common import * from fasthtml.jupyter import * from monsterui import franken from monsterui.all import Theme
def get_nb_paths(): root = Path() if IN_NOTEBOOK else Path("nbs/") return L(root.glob("*.ipynb")).sorted(reverse=True)
nbpaths = get_nb_paths() nbpaths
def get_date_from_iso8601_prefix(fname): "Gets date from first 10 chars YYYY-MM-DD of `fname`, where `fname` is like `2025-01-12-Get-Date-From-This.whatever" try: return datetime.fromisoformat(str(fname)[0:10]) except ValueError: return datetime.now()
def get_title_and_desc(fpath): nb = read_nb(fpath) title = nb.cells[0].source.lstrip("# ") desc = nb.cells[1].source return title,desc
app,rt = fast_app(pico=False)
def NBLink(title, desc, href, date): return Div( A(f"{date:%b %-d} • {title}", href=href, cls="text-md font-semibold hover:text-blue-600 no-underline block"), P(desc, cls="text-s text-gray-500 mt-0.5 mb-2"), cls="py-1 break-inside-avoid")
def mk_nblink_from_nbpath(nbpath): date = get_date_from_iso8601_prefix(nbpath.name) or datetime.now() return NBLink(*get_title_and_desc(nbpath), href=f'/nbs/{nbpath.name[:-6]}', date=date)
@rt def index(): nbpaths = get_nb_paths() return ( Theme.blue.headers(), Title("audrey.feldroy.com"), Div( H1('audrey.feldroy.com', cls="text-3xl font-bold mb-2"), P( "The experimental Jupyter notebooks of Audrey M. Roy Greenfeld. This website and all its notebooks are open-source at ", A("github.com/audreyfeldroy/audrey.feldroy.com", href="https://github.com/audreyfeldroy/arg-blog-fasthtml", cls="text-blue-600 hover:text-blue-800"), cls="mb-8 text-gray-600" ), Table( *nbpaths.map(mk_nblink_from_nbpath), ), cls="px-4 py-8 w-full columns-1 md:columns-2 lg:columns-3 gap-6" ) )
Improving this visually while providing extreme information density and compactness:
@rt def index(): nbpaths = get_nb_paths() return ( Script(src="https://unpkg.com/@tailwindcss/browser@4"), Title("audrey.feldroy.com"), Div( H1('audrey.feldroy.com', cls="text-2xl font-bold mb-2 dark:text-gray-100"), P( "The experimental Jupyter notebooks of Audrey M. Roy Greenfeld. This website and all its notebooks are open-source at ", A("github.com/audreyfeldroy/audrey.feldroy.com", href="https://github.com/audreyfeldroy/arg-blog-fasthtml", cls="text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300"), cls="mb-4 text-gray-600 dark:text-gray-300 text-sm" ), Div( *nbpaths.map(mk_nblink_from_nbpath), cls="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-x-6 gap-y-2" ), cls="mx-auto px-2 py-4 dark:bg-gray-900 min-h-screen" ), ) def NBLink(title, desc, href, date): return Div( A( Div( f"{date:%b %-d}", cls="text-xs font-medium text-gray-500 dark:text-gray-400" ), Div( title, cls="text-base font-medium leading-snug hover:text-blue-600 dark:text-gray-100 dark:hover:text-blue-400" ), P( desc, cls="text-xs text-gray-600 dark:text-gray-400 mt-0.5 line-clamp-2" ), href=href, cls="block no-underline hover:bg-gray-50 dark:hover:bg-gray-800 p-2 rounded transition-colors" ), cls="break-inside-avoid" )
server = JupyUvi(app)
HTMX(index)
# server.stop()