Description
Right now fills can only be used in the whole web and there’s no way to specify a fill that should be used only in some part, like only in the home, or only for a custom post type.
User Stories
As a Frontity theme consumer
I want to specify some data assertions for my fills
so that I can fill the slots only under certain conditions
Examples
- Use an ad fill only in the home.
- Use a newsletter fill only in the pages.
- Use a comments fill only in the posts.
Possible solution
While talking with @David in the Slot and Fill FD (Slot and Fill) we thought it could work like this.
Fills can have a assertions.data
property:
const state = {
fills: {
homeAd: {
slot: "Below header",
library: "Adsense",
props: {
adId: 123
},
assertions: {
data: {
isHome: true
}
}
},
postsAd: {
slot: "Below header",
library: "Adsense",
props: {
adId: 456
},
assertions: {
data: {
isPostType: true
}
}
},
categoriesAd: {
slot: "Below header",
library: "Adsense",
props: {
adId: 789
},
assertions: {
data: {
isTaxonomy: true,
taxonomy: category
}
}
}
}
};
The Slot
component will run those assertions against data
:
const Slot = ({
state,
actions,
libraries,
data: dataProp,
name,
...slotProps
}) => {
const data = dataProp || state.source.get(state.router.link);
const fills = Object.values(state.fills)
.find(fill => fill.name === name)
.sort((a, b) => a.priority > b.priority);
return fills.map(fill => {
const Fill = libraries.fills[fill.library];
const show = assert(data, fill.assertions);
return show ? <Fill {...slotProps} {...fill.props} /> : null;
});
};
As you can see, Slot
can receive a custom data
object. If it doesn’t, the assertions run against the current data
object.
To support more than “equal” assertions, they can be a value or an object. We can start with "equal"
and "notEqual"
and add more in the future.
The default will be “equal” so these are equivalent:
const assertions = {
data: {
isHome: true,
isHome: {
type: "equal",
value: true
}
}
};
Using an object opens new possibilities:
const state = {
fills: {
allPostTypesButProducts: {
assertions: {
data: {
isPostType: true,
type: {
type: "notEqual",
value: "products"
}
}
}
}
}
};
ORs could be done with arrays:
const state = {
fills: {
homeAndCategories: {
assertions: {
data: [
{
isHome: true
},
{
isTaxonomy: true,
taxonomy: "category"
}
]
}
}
}
};
This system can be used in other parts of Frontity, like the handlers of Source v2. It can also support other types of assertions, hence the assertions.data
property.