Views are used to render the contents of a page – or, in other words, values from page fields and any markup that is specific to a single template and thus shouldn't be in the layout file or partial files. Views are specific to a single template, and each template may have multiple views (if you want to render its contents in multiple ways).
Views have access to all parameters passed from the Controller trough the $view API variable in their local scope (
$this->parameter_name), and also a full access to ProcessWire's API. That being said, it is highly recommended that you don't add any sort of "business logic" into your views, even though they are (by default) regular PHP files.
Moving actual code to Controllers and dedicating views to markup generation only – output statements and simple control structures (if, else, foreach, etc.) – is an easy way to maintain proper separation of concerns.
A simple view file could look like this (/site/templates/views/home/default.php):
<?= $page->main ?> <?php if ($page->aside): ?> <aside> <?= $page->aside ?> </aside> <?php endif; ?>
Views and layouts together keep things DRY
As we've explained before, when using the concept of layout files, there's no need to include common files such as header.php or footer.php here – they're in the layout, and since the rendered page content (using a specific view file) gets injected into the midst of all that, the end result contains everything we need.
If you're wondering "why", the answer is simple: because DRY. Don't repeat yourself. A couple of innocent lines – such as
include "header.php" and
include "footer.php" – in every view file is a relatively small thing in itself, but what if you later on decide to rename those include files – or better yet, decide that you need more common files for all your views? That's a whole lot of updating right there, but had you instead included them in a layout file, you could just update that and be done with it.
For that reason alone it's better to have common stuff defined once, and then have the case-by-case content injected into that common frame – not the other way around.