Skip to content

SSG

SSG class to create a static site generator

Arguments

pages: dict[str, Path] Dictionary of routes and their corresponding pages static: Path The static directory scripts: Path The scripts directory styles: Path The styles directory server: dict[str, Path] Dictionary of routes and their corresponding server files

Attributes:

Name Type Description
pages dict[str, Path]

Dictionary of routes and their corresponding pages

static Path

The static directory

scripts Path

The scripts directory

styles Path

The styles directory

server dict[str, Path]

Dictionary of routes and their corresponding server files

Source code in vivid/http.py
class SSG:
    """
    SSG class to create a static site generator

    Arguments
    ---------
    pages: dict[str, Path]
        Dictionary of routes and their corresponding pages
    static: Path
        The static directory
    scripts: Path
        The scripts directory
    styles: Path
        The styles directory
    server: dict[str, Path]
        Dictionary of routes and their corresponding server files

    Attributes
    ----------
    pages: dict[str, Path]
        Dictionary of routes and their corresponding pages
    static: Path
        The static directory
    scripts: Path
        The scripts directory
    styles: Path
        The styles directory
    server: dict[str, Path]
        Dictionary of routes and their corresponding server files
    """

    def __init__(
        self,
        pages: dict[str, Path],
        static: Path,
        scripts: Path,
        styles: Path,
        server: dict[str, Path],
    ) -> None:
        self.pages = pages
        self.static = static
        self.scripts = scripts
        self.styles = styles
        self.server = server

    async def get_templates_with_data(
        self,
    ) -> AsyncGenerator[dict[str, tuple[Path, dict[str, t.Any] | None]], None]:
        """
        Get the templates with their corresponding data

        Arguments
        ---------
        None

        Yields
        ------
        dict[str, tuple[Path, dict[str, typing.Any] | None]]
            The templates with their corresponding data
        """
        for page in self.pages:
            if page == "/404" or page == "/500":
                yield {page: (self.pages[page], None)}
            else:
                if self.server.get(page):
                    mod = await load_server(self.server[page])
                    if mod:
                        data = await get_static_load_data(mod)
                        if data:
                            yield {page: (self.pages[page], data.body)}
                        else:
                            yield {page: (self.pages[page], None)}
                    else:
                        yield {page: (self.pages[page], None)}
                else:
                    yield {page: (self.pages[page], None)}

    async def build(self, dest: Path) -> None:
        """
        Build the static site

        Arguments
        ---------
        dest: Path
            The destination directory

        Returns
        -------
        None
        """
        console.print(f"[#8B5CF6 bold]🔨 Building to {dest.as_posix()}[/#8B5CF6 bold]\n")
        async for pageAndData in self.get_templates_with_data():
            for page, (template, data) in pageAndData.items():
                body = return_template(template)
                if body:
                    if data:
                        _body = render_template(body, data)
                        if isinstance(_body, Exception):
                            raise _body
                        try:
                            create_file_from_route(page, _body, dest)
                            console.print(f"[#0EA5E9]✅ {page} created[/#0EA5E9]")
                        except Exception:
                            console.print_exception()
                    else:
                        try:
                            console.print(f"[#0EA5E9]✅ {page} created[/#0EA5E9]")
                            create_file_from_route(page, body, dest)
                        except Exception:
                            console.print_exception()
        try:
            console.print("[#8B5CF6 bold]🔨 Copying static files[/#8B5CF6 bold]")
            copy_static_files_to(self.static, dest / "static")
        except Exception:
            console.print_exception()
        finally:
            console.print("[#0EA5E9 bold]✅ Copied static[/#0EA5E9 bold]")
        try:
            console.print("[#8B5CF6 bold]🔨 Copying scripts[/#8B5CF6 bold]")
            copy_static_files_to(self.scripts, dest / "scripts")
        except Exception:
            console.print_exception()
        finally:
            console.print("[#0EA5E9 bold]✅ Copied scripts[/#0EA5E9 bold]")
        try:
            console.print("[#8B5CF6 bold]🔨 Copying styles[/#8B5CF6 bold]")
            copy_static_files_to(self.styles, dest / "styles")
        except Exception:
            console.print_exception()
        finally:
            console.print("[#0EA5E9 bold]✅ Copied styles[/#0EA5E9 bold]")
        console.print("[#8B5CF6 bold]\n✅ Build complete\n[/#8B5CF6 bold]")
        console.print("[#FACC15 bold]âš  Make sure to fix the srcs and hrefs of scripts and stlyes[/#FACC15 bold]")

build(dest) async

Build the static site

Arguments

dest: Path The destination directory

Returns:

Type Description
None
Source code in vivid/http.py
async def build(self, dest: Path) -> None:
    """
    Build the static site

    Arguments
    ---------
    dest: Path
        The destination directory

    Returns
    -------
    None
    """
    console.print(f"[#8B5CF6 bold]🔨 Building to {dest.as_posix()}[/#8B5CF6 bold]\n")
    async for pageAndData in self.get_templates_with_data():
        for page, (template, data) in pageAndData.items():
            body = return_template(template)
            if body:
                if data:
                    _body = render_template(body, data)
                    if isinstance(_body, Exception):
                        raise _body
                    try:
                        create_file_from_route(page, _body, dest)
                        console.print(f"[#0EA5E9]✅ {page} created[/#0EA5E9]")
                    except Exception:
                        console.print_exception()
                else:
                    try:
                        console.print(f"[#0EA5E9]✅ {page} created[/#0EA5E9]")
                        create_file_from_route(page, body, dest)
                    except Exception:
                        console.print_exception()
    try:
        console.print("[#8B5CF6 bold]🔨 Copying static files[/#8B5CF6 bold]")
        copy_static_files_to(self.static, dest / "static")
    except Exception:
        console.print_exception()
    finally:
        console.print("[#0EA5E9 bold]✅ Copied static[/#0EA5E9 bold]")
    try:
        console.print("[#8B5CF6 bold]🔨 Copying scripts[/#8B5CF6 bold]")
        copy_static_files_to(self.scripts, dest / "scripts")
    except Exception:
        console.print_exception()
    finally:
        console.print("[#0EA5E9 bold]✅ Copied scripts[/#0EA5E9 bold]")
    try:
        console.print("[#8B5CF6 bold]🔨 Copying styles[/#8B5CF6 bold]")
        copy_static_files_to(self.styles, dest / "styles")
    except Exception:
        console.print_exception()
    finally:
        console.print("[#0EA5E9 bold]✅ Copied styles[/#0EA5E9 bold]")
    console.print("[#8B5CF6 bold]\n✅ Build complete\n[/#8B5CF6 bold]")
    console.print("[#FACC15 bold]âš  Make sure to fix the srcs and hrefs of scripts and stlyes[/#FACC15 bold]")

get_templates_with_data() async

Get the templates with their corresponding data

Arguments

None

Yields:

Type Description
dict[str, tuple[Path, dict[str, Any] | None]]

The templates with their corresponding data

Source code in vivid/http.py
async def get_templates_with_data(
    self,
) -> AsyncGenerator[dict[str, tuple[Path, dict[str, t.Any] | None]], None]:
    """
    Get the templates with their corresponding data

    Arguments
    ---------
    None

    Yields
    ------
    dict[str, tuple[Path, dict[str, typing.Any] | None]]
        The templates with their corresponding data
    """
    for page in self.pages:
        if page == "/404" or page == "/500":
            yield {page: (self.pages[page], None)}
        else:
            if self.server.get(page):
                mod = await load_server(self.server[page])
                if mod:
                    data = await get_static_load_data(mod)
                    if data:
                        yield {page: (self.pages[page], data.body)}
                    else:
                        yield {page: (self.pages[page], None)}
                else:
                    yield {page: (self.pages[page], None)}
            else:
                yield {page: (self.pages[page], None)}