Skip to content

MkShowcase

Show source on GitHub

Node for showing a html-based image grid.

Description

Manages row / column positioning. Mainly intended for MkCards, but can also include other markdown (there are limits though.) When adding MkCards, then addtional CSS is required.

Example: From TOML format

Jinja

{{
'
["Card 1"]
title = "Some title 1"
image = "https://picsum.photos/300"
caption = "Some **markdown**"
["Card 2"]
title = "Some title 2"
image = "https://picsum.photos/301"
caption = "Some **markdown**"
' | load_toml | MkShowcase
}}

Python

MkShowcase([MkCard('Some title 1', 'http... caption='Some **markdown**'), MkCard('Some title 2', 'http... caption='Some **markdown**')])

Some title 1
Some markdown

Some title 2
Some markdown

<div class="row">
  <div class="column">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Some title 1" style="width:200px,height:200px">
    <div class="overlay">Some **markdown**</div>
    </div>
    <p>
    <button>Some title 1</button>
    </p>
    </div>
  </div>
  <div class="column">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/301" alt="Some title 2" style="width:200px,height:200px">
    <div class="overlay">Some **markdown**</div>
    </div>
    <p>
    <button>Some title 2</button>
    </p>
    </div>
  </div>
</div>
<div class="row">
  <div class="column">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Some title 1" style="width:200px,height:200px">
    <div class="overlay">Some **markdown**</div>
    </div>
    <p>
    <button>Some title 1</button>
    </p>
    </div>
  </div>
  <div class="column">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/301" alt="Some title 2" style="width:200px,height:200px">
    <div class="overlay">Some **markdown**</div>
    </div>
    <p>
    <button>Some title 2</button>
    </p>
    </div>
  </div>
</div>
MkShowcase
MkCard('Some title 1', 'https://picsum.photos/300', caption='Some **markdown**')
MkCard('Some title 2', 'https://picsum.photos/301', caption='Some **markdown**')

Example: Manual

Jinja

{% set url = "https://phil65.github.io/mknodes/" %}
{% set img_url = "https://picsum.photos/300" %}
{{ ["Title 0" | MkCard(target=url, image=img_url, caption="Caption 0"),
    "Title 1" | MkCard(target=url, image=img_url, caption="Caption 1"),
    "Title 2" | MkCard(target=url, image=img_url, caption="Caption 2"),
    "Title 3" | MkCard(target=url, image=img_url, caption="Caption 3"),
    "Title 4" | MkCard(target=url, image=img_url, caption="Caption 4"),
    "Title 5" | MkCard(target=url, image=img_url, caption="Caption 5")] | MkShowcase }}

Python

MkContainer([...])
<a href="https://phil65.github.io/mknodes/">
<div class="card">
<div class="showcase-container">
<img src="https://picsum.photos/300" alt="Title 0" style="width:200px,height:200px">
<div class="overlay">Caption 0</div>
</div>
<p>
<button>Title 0</button>
</p>
</div>
</a>


<a href="https://phil65.github.io/mknodes/">
<div class="card">
<div class="showcase-container">
<img src="https://picsum.photos/300" alt="Title 1" style="width:200px,height:200px">
<div class="overlay">Caption 1</div>
</div>
<p>
<button>Title 1</button>
</p>
</div>
</a>


<a href="https://phil65.github.io/mknodes/">
<div class="card">
<div class="showcase-container">
<img src="https://picsum.photos/300" alt="Title 2" style="width:200px,height:200px">
<div class="overlay">Caption 2</div>
</div>
<p>
<button>Title 2</button>
</p>
</div>
</a>


<a href="https://phil65.github.io/mknodes/">
<div class="card">
<div class="showcase-container">
<img src="https://picsum.photos/300" alt="Title 3" style="width:200px,height:200px">
<div class="overlay">Caption 3</div>
</div>
<p>
<button>Title 3</button>
</p>
</div>
</a>


<a href="https://phil65.github.io/mknodes/">
<div class="card">
<div class="showcase-container">
<img src="https://picsum.photos/300" alt="Title 4" style="width:200px,height:200px">
<div class="overlay">Caption 4</div>
</div>
<p>
<button>Title 4</button>
</p>
</div>
</a>


<a href="https://phil65.github.io/mknodes/">
<div class="card">
<div class="showcase-container">
<img src="https://picsum.photos/300" alt="Title 5" style="width:200px,height:200px">
<div class="overlay">Caption 5</div>
</div>
<p>
<button>Title 5</button>
</p>
</div>
</a>


<div class="row">
  <div class="column">
    <a href="https://phil65.github.io/mknodes/">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Title 0" style="width:200px,height:200px">
    <div class="overlay">Caption 0</div>
    </div>
    <p>
    <button>Title 0</button>
    </p>
    </div>
    </a>
  </div>
  <div class="column">
    <a href="https://phil65.github.io/mknodes/">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Title 1" style="width:200px,height:200px">
    <div class="overlay">Caption 1</div>
    </div>
    <p>
    <button>Title 1</button>
    </p>
    </div>
    </a>
  </div>
  <div class="column">
    <a href="https://phil65.github.io/mknodes/">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Title 2" style="width:200px,height:200px">
    <div class="overlay">Caption 2</div>
    </div>
    <p>
    <button>Title 2</button>
    </p>
    </div>
    </a>
  </div>
</div><div class="row">
  <div class="column">
    <a href="https://phil65.github.io/mknodes/">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Title 3" style="width:200px,height:200px">
    <div class="overlay">Caption 3</div>
    </div>
    <p>
    <button>Title 3</button>
    </p>
    </div>
    </a>
  </div>
  <div class="column">
    <a href="https://phil65.github.io/mknodes/">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Title 4" style="width:200px,height:200px">
    <div class="overlay">Caption 4</div>
    </div>
    <p>
    <button>Title 4</button>
    </p>
    </div>
    </a>
  </div>
  <div class="column">
    <a href="https://phil65.github.io/mknodes/">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Title 5" style="width:200px,height:200px">
    <div class="overlay">Caption 5</div>
    </div>
    <p>
    <button>Title 5</button>
    </p>
    </div>
    </a>
  </div>
</div>
<p><a href="https://phil65.github.io/mknodes/"></p>
<div class="card">
<div class="showcase-container">
<img src="https://picsum.photos/300" alt="Title 0" style="width:200px,height:200px">
<div class="overlay">Caption 0</div>
</div>
<p>
<button>Title 0</button>
</p>
</div>
<p></a></p>
<p><a href="https://phil65.github.io/mknodes/"></p>
<div class="card">
<div class="showcase-container">
<img src="https://picsum.photos/300" alt="Title 1" style="width:200px,height:200px">
<div class="overlay">Caption 1</div>
</div>
<p>
<button>Title 1</button>
</p>
</div>
<p></a></p>
<p><a href="https://phil65.github.io/mknodes/"></p>
<div class="card">
<div class="showcase-container">
<img src="https://picsum.photos/300" alt="Title 2" style="width:200px,height:200px">
<div class="overlay">Caption 2</div>
</div>
<p>
<button>Title 2</button>
</p>
</div>
<p></a></p>
<p><a href="https://phil65.github.io/mknodes/"></p>
<div class="card">
<div class="showcase-container">
<img src="https://picsum.photos/300" alt="Title 3" style="width:200px,height:200px">
<div class="overlay">Caption 3</div>
</div>
<p>
<button>Title 3</button>
</p>
</div>
<p></a></p>
<p><a href="https://phil65.github.io/mknodes/"></p>
<div class="card">
<div class="showcase-container">
<img src="https://picsum.photos/300" alt="Title 4" style="width:200px,height:200px">
<div class="overlay">Caption 4</div>
</div>
<p>
<button>Title 4</button>
</p>
</div>
<p></a></p>
<p><a href="https://phil65.github.io/mknodes/"></p>
<div class="card">
<div class="showcase-container">
<img src="https://picsum.photos/300" alt="Title 5" style="width:200px,height:200px">
<div class="overlay">Caption 5</div>
</div>
<p>
<button>Title 5</button>
</p>
</div>
<p></a></p>
<div class="row">
  <div class="column">
    <a href="https://phil65.github.io/mknodes/">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Title 0" style="width:200px,height:200px">
    <div class="overlay">Caption 0</div>
    </div>
    <p>
    <button>Title 0</button>
    </p>
    </div>
    </a>
  </div>
  <div class="column">
    <a href="https://phil65.github.io/mknodes/">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Title 1" style="width:200px,height:200px">
    <div class="overlay">Caption 1</div>
    </div>
    <p>
    <button>Title 1</button>
    </p>
    </div>
    </a>
  </div>
  <div class="column">
    <a href="https://phil65.github.io/mknodes/">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Title 2" style="width:200px,height:200px">
    <div class="overlay">Caption 2</div>
    </div>
    <p>
    <button>Title 2</button>
    </p>
    </div>
    </a>
  </div>
</div>
<div class="row">
  <div class="column">
    <a href="https://phil65.github.io/mknodes/">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Title 3" style="width:200px,height:200px">
    <div class="overlay">Caption 3</div>
    </div>
    <p>
    <button>Title 3</button>
    </p>
    </div>
    </a>
  </div>
  <div class="column">
    <a href="https://phil65.github.io/mknodes/">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Title 4" style="width:200px,height:200px">
    <div class="overlay">Caption 4</div>
    </div>
    <p>
    <button>Title 4</button>
    </p>
    </div>
    </a>
  </div>
  <div class="column">
    <a href="https://phil65.github.io/mknodes/">
    <div class="card">
    <div class="showcase-container">
    <img src="https://picsum.photos/300" alt="Title 5" style="width:200px,height:200px">
    <div class="overlay">Caption 5</div>
    </div>
    <p>
    <button>Title 5</button>
    </p>
    </div>
    </a>
  </div>
</div>
MkContainer
╰── MkCard('Title 0', 'https://picsum.photos/300', caption='Caption 0', target='https://phil65.github.io/mknodes/')
╰── MkCard('Title 1', 'https://picsum.photos/300', caption='Caption 1', target='https://phil65.github.io/mknodes/')
╰── MkCard('Title 2', 'https://picsum.photos/300', caption='Caption 2', target='https://phil65.github.io/mknodes/')
╰── MkCard('Title 3', 'https://picsum.photos/300', caption='Caption 3', target='https://phil65.github.io/mknodes/')
╰── MkCard('Title 4', 'https://picsum.photos/300', caption='Caption 4', target='https://phil65.github.io/mknodes/')
├── MkCard('Title 5', 'https://picsum.photos/300', caption='Caption 5', target='https://phil65.github.io/mknodes/')
╰── MkShowcase([MkCard('Title 0', 'https://p...//phil65.github.io/mknodes/'), MkCard('Title 1', 'https://p...//phil65.github.io/mknodes/'), MkCard('Title 2', 'https://p...//phil65.github.io/mknodes/'), MkCard('Title 3', 'https://p...//phil65.github.io/mknodes/'), MkCard('Title 4', 'https://p...//phil65.github.io/mknodes/'), MkCard('Title 5', 'https://p...//phil65.github.io/mknodes/')])
╰── MkCard('Title 0', 'https://picsum.photos/300', caption='Caption 0', target='https://phil65.github.io/mknodes/')
╰── MkCard('Title 1', 'https://picsum.photos/300', caption='Caption 1', target='https://phil65.github.io/mknodes/')
╰── MkCard('Title 2', 'https://picsum.photos/300', caption='Caption 2', target='https://phil65.github.io/mknodes/')
╰── MkCard('Title 3', 'https://picsum.photos/300', caption='Caption 3', target='https://phil65.github.io/mknodes/')
╰── MkCard('Title 4', 'https://picsum.photos/300', caption='Caption 4', target='https://phil65.github.io/mknodes/')
├── MkCard('Title 5', 'https://picsum.photos/300', caption='Caption 5', target='https://phil65.github.io/mknodes/')

Bases: MkContainer

add_card

add_card(
    title: str,
    image: str,
    target: str | mk.MkPage | mk.MkNav | None = None,
    caption: str | None = None,
)

Parameters:

Name Type Description Default
title str

Card title

required
image str

link to the Image

required
target str | MkPage | MkNav | None

Optional link for the card

None
caption str | None

Image caption

None
Name Children Inherits
MkContainer
mknodes.basenodes.mkcontainer
A node containing other MkNodes.
graph TD
  94854582839552["mkshowcase.MkShowcase"]
  94854582919984["mkcontainer.MkContainer"]
  94854582916880["mknode.MkNode"]
  94854582838576["node.Node"]
  140544995341632["builtins.object"]
  94854582919984 --> 94854582839552
  94854582916880 --> 94854582919984
  94854582838576 --> 94854582916880
  140544995341632 --> 94854582838576
/home/runner/work/mknodes/mknodes/mknodes/basenodes/mkshowcase/metadata.toml
[metadata]
icon = "mdi:view-grid"
name = "MkShowcase"

[examples.toml]
title = "From TOML format"
jinja = """
{{
'
["Card 1"]
title = "Some title 1"
image = "https://picsum.photos/300"
caption = "Some **markdown**"
["Card 2"]
title = "Some title 2"
image = "https://picsum.photos/301"
caption = "Some **markdown**"
' | load_toml | MkShowcase
}}
"""

[examples.cards]
title = "Manual"
python = """
import mknodes as mk

node = mk.MkShowcase()
for i in range(6):
    node.add_card(
        target="https://phil65.github.io/mknodes/",
        title=f"Title {i}",
        image="https://picsum.photos/300",
        caption=f"Caption {i}",
    )
node
"""
jinja = """
{% set url = "https://phil65.github.io/mknodes/" %}
{% set img_url = "https://picsum.photos/300" %}
{{ ["Title 0" | MkCard(target=url, image=img_url, caption="Caption 0"),
    "Title 1" | MkCard(target=url, image=img_url, caption="Caption 1"),
    "Title 2" | MkCard(target=url, image=img_url, caption="Caption 2"),
    "Title 3" | MkCard(target=url, image=img_url, caption="Caption 3"),
    "Title 4" | MkCard(target=url, image=img_url, caption="Caption 4"),
    "Title 5" | MkCard(target=url, image=img_url, caption="Caption 5")] | MkShowcase }}
"""
[output.markdown]
template = """
{% for items in node.items | batch(node.column_count) %}
<div class="row">
{% for item in items %}
  <div class="column">
{{ item | string | indent(first=True) }}  </div>
{% endfor %}
</div>{% endfor %}
"""
mknodes.basenodes.mkshowcase.MkShowcase
class MkShowcase(mkcontainer.MkContainer):
    """Node for showing a html-based image grid.

    Manages row / column positioning.
    Mainly intended for MkCards, but can also include other markdown (there are limits
    though.)
    When adding MkCards, then addtional CSS is required.
    """

    ICON = "material/view-grid"

    def __init__(
        self,
        items: list[str | mknode.MkNode] | None = None,
        *,
        column_count: int = 3,
        **kwargs,
    ):
        self.column_count = column_count
        if isinstance(items, str | os.PathLike):
            text = pathhelpers.load_file_cached(str(items))
            data = tomllib.loads(text)
            items = [mkcard.MkCard(**dct) for dct in data.values()]
        elif isinstance(items, dict):
            items = [mkcard.MkCard(**dct) for dct in items.values()]
        super().__init__(content=items or [], **kwargs)

    def to_child_node(self, item) -> mknode.MkNode:
        match item:
            case mkpage.MkPage():
                return mkcard.MkCard(
                    target=item,
                    title=item.title or " ",
                    caption=item.subtitle or " ",
                    image=":material-tab:",
                    parent=self,
                )
            case mkcard.MkCard():
                return item
            case _:
                return super().to_child_node(item)

    def _to_markdown(self) -> str:
        text = ""
        for items in filters.do_batch(self.items, self.column_count):
            text += '<div class="row">'
            for item in items:
                text += '\n  <div class="column">\n'
                text += textwrap.indent(str(item), "    ")
                text += "  </div>"
            text += "\n</div>"
        return text

    def add_card(
        self,
        title: str,
        image: str,
        target: str | mk.MkPage | mk.MkNav | None = None,
        caption: str | None = None,
    ):
        """Add an image card to the node.

        Arguments:
            title: Card title
            image: link to the Image
            target: Optional link for the card
            caption: Image caption
        """
        card = mkcard.MkCard(target=target, title=title, image=image, caption=caption)
        self.append(card)