I could get up on a soap box and speak for days on this. In fact I have. The Page Template Mistake.
The role of Information Hiding
The first concern you must address (from my viewpoint) is: You need to separate this decision making from your actual code build.
Or put differently: Your components should make as few assumptions about the Information Architecture as possible
In software engineering this loosely called Information Hiding. It's a good practice in software development, and it holds true for your Sitecore solutions as well.
In computer science, information hiding is the principle of
segregation of the design decisions in a computer program that are
most likely to change, thus protecting other parts of the program from
extensive modification if the design decision is changed. The
protection involves providing a stable interface which protects the
remainder of the program from the implementation (the details that are
most likely to change).
Translated into "Sitecore speak", this means you need to declare an interface between your Sitecore Information Architecture and your component - creating a clear definition of what information is the component is made aware of. Subsequently, everything else is "off limits".
Fortunately we have a method for doing exactly that - it's the Datasource Template
The shared interface
So, we've established that any component should have a clearly defined interface. We then connect the two, by setting the Datasource Template
on your rendering item.
The Datasource Template
looks like this:
And we reference the template on the MetaHead Rendering
like this:
So far so good. You've established a basic "contract" between Sitecore and your component implementation. (As an aside, there are ways this can be overridden, so it's not a strict "guarantee". It's usually good enough however.)
The next step is to use this in your code.
The design pattern
One of the oldest principles in Sitecore Information Architecture, is how the code treats the Datasource it is given given. When Sitecore was originally envisioned, I suspect sites were being built primarily using XSLT. As such, it makes sense to pay attention to how the XSLT engine treats a Datasource
sent to a component.
We find this in the Presentation Component XSL Reference:
A rendering can retrieve data from its data source item. The $sc_item
variable represents the data source item for an XSL rendering. If the
developer does not specify a data source item for a rendering, the
default data source item is the context item, and $sc_item and
$sc_currentitem are the same item.
Translated into technologies we use today, it basically says if a Datasource has been set, use it. If not, fall back to Context.Item
Before doing anything else, your code should ensure that the item you get from the process above actually implements the template you defined in the contract above. (I know Glass Mapper can do this. It's also what my own Datalift project is all about.)
Now implement your component; assume nothing about data outside your defined component template. No Context.Item
, no Context.Database
, nothing at all. That one item you end up with - will have all of that.
I like to call this item your ActionItem
, simply to distinguish it from other terms that are used a bit loosely (like Datasource Item
and Current Item
.)
ActionItem.Database
ActionItem.Language
- and so on.
You should essentially never need to touch Context.Anything
using this approach.
We have now come full circle and I can explain how this relates to your question. (And more importantly, why you shouldn't spend a whole lot of time worrying about exactly this.)
Page Templates.
If you follow the above recommendations, you're largely free of constraints in your Page Templates - and you're also free to change your mind later on.
The role of the Page Template
So in your question you specifically ask for, where a field
should live. I say; you don't make these decisions on field
level. You make them on template level. Where each template matches a component. You don't want components cherry picking fields
left, right, and center - you want Information Hiding so the components know nothing that isn't in the contract you've set up.
To demonstrate and visualize what I mean, I've set up a few more component templates:
And to match it, I've added some matching rendering definitions.
We'll pretend I've coded them as described above ;-)
And now we're at the key question: "How should I decide, what goes on the Page Templates?". First, let's make a Page Template called Homepage
.
I then say to myself; "Well for this type of page - I will always have at least one of each of my components on the page. (There may be additional promo spots, but I will always have one.)"
In that case, we're good to use our component templates as base templates for our page template. We go to the Template Builder ribbon, select Base templates
, and add all of them.
And - this should come as no surprise - we end up with a Page Template that now has fields, for all of these components.
And your code will work. Create new instances of this new Page Template, add your components to Presentation Details, and don't set a Datasource for them... everything works.
Let's create another one called Section Page
. This time we're not so sure there's always a Promotion on it.
So, we won't use the Promotion template as a base for our Page Template itself. But you can of course, still add a promotion to your Presentation Details and set a Datasource for it. And so on.
See what I'm getting at? It doesn't really matter. You can create a hundred Page Templates if you want (you probably shouldn't) - and if there are certain types of pages in your solution that would need to be under Workflow? Well then you make "thick" Page Templates, like I just did here.
Do you have other types of pages that need to be as flexible as possible - an almost blank "canvas" for your editors to roam freely in? Well then make a thin one. Possibly not inheriting from anything other than maybe MetaHead
, Header
and Footer
.
Need some pages to enter a translation flow? Inherit from the components that are part of this flow, and make a Page Template for that.
My point is; it doesn't really matter so much. As long as you're using solid implementation practices - you can freely mold your Information Architecture to suit your requirements. And not a single line of code in your solution should need to be changed in this process.
Which, I'm guessing, is the primary reason you're asking this question at all.