Skip to content

MkTimeline

Show source on GitHub

Node to show a JavaScript-supported Timeline.

Description

Consists of cards which slide in and out once they enter / leave the screen.

Example: From TOML format

Jinja

{{
"
['Step 1']
title = 'test'
content = 'Some **markdown**'
image = 'https://picsum.photos/400'
['Step 2']
title = 'test'
content = 'Some **markdown**'
image = 'https://picsum.photos/401'

" | load_toml | MkTimeline
}}

Python

MkTimeline([...])

test

Some markdown

test

Some markdown

<section class="timeline">
<div class="timeline-item">
<div class="timeline-img"></div>
<div class="timeline-content timeline-card js--fadeInLeft">
<div style="background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.4)), url(https://picsum.photos/400) center center no-repeat; background-size: cover;" class="timeline-img-header">
<p>
<h2>test</h2>
</p>
</div>
<p>
<p>Some <strong>markdown</strong>
</p>
</p>
</div>
</div>
<div class="timeline-item">
<div class="timeline-img"></div>
<div class="timeline-content timeline-card js--fadeInRight">
<div style="background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.4)), url(https://picsum.photos/401) center center no-repeat; background-size: cover;" class="timeline-img-header">
<p>
<h2>test</h2>
</p>
</div>
<p>
<p>Some <strong>markdown</strong>
</p>
</p>
</div>
</div>
</section>
<section class="timeline">
<div class="timeline-item">
<div class="timeline-img"></div>
<div class="timeline-content timeline-card js--fadeInLeft">
<div style="background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.4)), url(https://picsum.photos/400) center center no-repeat; background-size: cover;" class="timeline-img-header">
<p>
<h2>test</h2>
</p>
</div>
<p>
<p>Some <strong>markdown</strong>
</p>
</p>
</div>
</div>
<div class="timeline-item">
<div class="timeline-img"></div>
<div class="timeline-content timeline-card js--fadeInRight">
<div style="background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.4)), url(https://picsum.photos/401) center center no-repeat; background-size: cover;" class="timeline-img-header">
<p>
<h2>test</h2>
</p>
</div>
<p>
<p>Some <strong>markdown</strong>
</p>
</p>
</div>
</div>
</section>
MkTimeline
├── MkTimelineItem('test', None, image='https://picsum.photos/400')
│   ╰── MkText('Some **markdown**')
╰── MkTimelineItem('test', None, image='https://picsum.photos/401')
    ╰── MkText('Some **markdown**')

Bases: MkContainer

__init__

__init__(items: list | str | dict | PathLike[str] | None = None, **kwargs: Any)

Parameters:

Name Type Description Default
items list | str | dict | PathLike[str] | None

Timeline items or a path to a TOML file containing timeline data

None
kwargs Any

Keyword arguments passed to parent

{}

add_item

add_item(
    title: str = "",
    content: str | MkNode = "",
    *,
    label: str = "",
    link: str = "",
    button_text: str = "More",
    image: str = "",
    **kwargs: Any
)
Name Children Inherits
MkContainer
mknodes.basenodes.mkcontainer
A node containing other MkNodes.
graph TD
  94721311965552["mktimeline.MkTimeline"]
  94721311697232["mkcontainer.MkContainer"]
  94721308848336["mknode.MkNode"]
  94721311766592["node.Node"]
  140564252373184["builtins.object"]
  94721311697232 --> 94721311965552
  94721308848336 --> 94721311697232
  94721311766592 --> 94721308848336
  140564252373184 --> 94721311766592
/home/runner/work/mknodes/mknodes/mknodes/basenodes/mktimeline/metadata.toml
[metadata]
icon = "mdi:timeline"
name = "MkTimeline"

[[resources.css]]
filename = "timeline.css"

[[resources.js]]
is_library = true
link = "https://cdn.jsdelivr.net/npm/scrollreveal@3.4.0/dist/scrollreveal.min.js"

[[resources.js]]
link = "https://code.jquery.com/jquery-2.2.4.min.js"
is_library = true

[[resources.js]]
filename = "timeline.js"

[examples.toml]
title = "From TOML format"
jinja = """
{{
"
['Step 1']
title = 'test'
content = 'Some **markdown**'
image = 'https://picsum.photos/400'
['Step 2']
title = 'test'
content = 'Some **markdown**'
image = 'https://picsum.photos/401'

" | load_toml | MkTimeline
}}
"""

[fragments]
item = """
<div class="timeline-item">
<div class="timeline-img"></div>
<div class="timeline-content{{ " timeline-card" if node.image else "" }} js--fadeIn{{ node.fade_direction | capitalize }}">
{% if node.image %}
<div style="background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.4)), url({{ node.image }}) center center no-repeat; background-size: cover;" class="timeline-img-header">
<p>
<h2>{{ node.title }}</h2>
</p>
</div>
{% else %}
<h2>{{ node.title }}</h2>
{% endif %}
{% if node.label %}
<div class="date">{{ node.label }}</div>
{% endif %}
<p>
{{ node.content | to_html }}
</p>
{{ node.button_text | html_link(node.link, class_="bnt-more") }}
</div>
</div>
"""

# [output.markdown]
# template = """


# <section class="timeline">
# {% for item in node.items %}
# {{ "fragments/item" | render_template(node=item) }}
# {% endfor %}
# </section>


# """
mknodes.basenodes.mktimeline.MkTimeline
class MkTimeline(mkcontainer.MkContainer):
    """Node to show a JavaScript-supported Timeline.

    Consists of cards which slide in and out once they enter / leave the screen.
    """

    ICON = "material/timeline"
    JS_FILES = [
        resources.JSFile(JQUERY_LINK, is_library=True),
        resources.JSFile(SCROLLREVEAL_LINK, is_library=True),
        resources.JSText(SCRIPT, "scrollreveal.js"),  # type: ignore[list-item]
        resources.JSFile("timeline.js"),
    ]
    CSS = [resources.CSSFile("timeline.css")]
    items: list[MkTimelineItem]

    def __init__(
        self,
        items: list | str | dict | os.PathLike[str] | None = None,
        **kwargs: Any,
    ):
        """Constructor.

        Args:
            items: Timeline items or a path to a TOML file containing timeline data
            kwargs: Keyword arguments passed to parent
        """
        if isinstance(items, str | os.PathLike):
            text = pathhelpers.load_file_cached(str(items))
            data = tomllib.loads(text)
            items = [MkTimelineItem(**step) for step in data.values()]
        elif isinstance(items, dict):
            items = [MkTimelineItem(**step) for step in items.values()]
        super().__init__(items, **kwargs)

    def get_element(self) -> xml.Section:
        root = xml.Section("timeline")
        for i, item in enumerate(self.items):
            item.fade_direction = "left" if i % 2 == 0 else "right"
            elem = item.get_element()
            root.append(elem)
        return root

    def _to_markdown(self) -> str:
        root = self.get_element()
        return "\n\n" + root.to_string(space="") + "\n\n"

    def add_item(
        self,
        title: str = "",
        content: str | mknode.MkNode = "",
        *,
        label: str = "",
        link: str = "",
        button_text: str = "More",
        image: str = "",
        **kwargs: Any,
    ):
        """Add a timeline item.

        title: Item header
        content: Markdown for content
        label: Label to be displayed in small box at the top
        link: Optional button-link. Text of button can be set via button_text
        button_text: Text for the link button.
        image: Optional image for the item
        kwargs: keyword arguments passed to parent
        """
        item = MkTimelineItem(
            title=title,
            content=content,
            label=label,
            link=link,
            button_text=button_text,
            image=image,
            **kwargs,
        )
        self += item
        return item