Layout System
A layout is the structure of a presentation slide.
It defines what content will be displayed and the relations between different parts of it. Each part of the content can be a primitive type or a component.
We define layouts as Pydantic models, since they are fed into LLMs to guide their output.
Understanding layouts
Section titled “Understanding layouts”Basic layout
Section titled “Basic layout”Everything is best explained with an example. Let’s imagine a simple layout with two placeholders: one for a headline and one for the content.
from pydantic import BaseModel
class Layout(BaseModel): headline: str content: strRepeating content
Section titled “Repeating content”Now, let’s suppose we want to add a second headline and content to the layout. We could do this by adding more placeholders:
from pydantic import BaseModel
class Layout(BaseModel): headline: str content: str headline_2: str content_2: strHowever, this is not very flexible. If in the future we want to keep adding more placeholders following the same pattern, we would have to add more fields to the layout. This is not ideal.
Instead, we can offload this repeating pattern to an Item, and then add as
many items as we want to the layout.
So, we can redefine our previous layout as follows:
from pydantic import BaseModel
class Item(BaseModel): headline: str content: str
class Layout(BaseModel): items: list[Item]This way, we can add as many items as we want to the layout in a dynamic way.
Components
Section titled “Components”A components is, in essence, any indivisible part of content that can not be described by a single primitive type. For example, an image, an icon, a chart…
Components are defined as Pydantic models, and they are used in layouts and items.
Let’s add an image to our layout in the examples above:
from pydantic import BaseModel
class Image(BaseModel): url: str caption: strfrom pydantic import BaseModelfrom image import Image
class Item(BaseModel): headline: str content: str
class Layout(BaseModel): image: Image items: list[Item]Here we have added the image to the layout, but nothing stops us from adding it to the item instead. In that case, we would have as many images as items in the slide.
The ComposableItem class
Section titled “The ComposableItem class”We have seen how Component, Item and Layout can be used to define layouts.
However, there is something subtle that is easy to miss, and that would bring a
lot of headaches when generating content.
The first option is not great, since it requires us to add specific logic on how to handle each layout or, to have fixed names for content fields.
Instead, we can probe the layout during runtime and dynamically generate the
content based on the its structure. For that, we make use of the
ComposableItem class. This class exposes two methods:
from pydantic import BaseModel
class ComposableItem(BaseModel): def has_component(self, component: type[Component]) -> bool: ...
def get_component(self, component: type[Component]) -> Component | None: ...With these, we can decide what to generate for any given layout. For example:
from image import Image
image = layout.get_component(Image)if image: image = generate_image()