1

I would like to include a stylesheet and other documents only if they are present in the presentation layer. How is it recommended to handle it? I show the two alternatives I see now in their respective layers:

Presentation:

<?php
$internalpath = "/internal/path/style.css";
if (!file_exists($internalpath))
  throw new Exception("Couldn't find style.css in " . $internalpath);
else {
?>
<link href="/external/path/style.css" rel="stylesheet" type="text/css">
<?php } ?>

Problem: it is bloating the view with business logic

Business logic:

<?php
$internalpath = "/internal/path/style.css";
if (!file_exists($internalpath))
  throw new Exception("Couldn't find style.css in " . $internalpath);
else
  $style = '<link href="/external/path/style.css" rel="stylesheet" type="text/css">';

// ...
?>

Problem: it is bloating the business logic with part of the view.

How can I separate these concerns properly? Is there any other simple alternative I'm not seeing?

Francisco Presencia
  • 8,732
  • 6
  • 46
  • 90

2 Answers2

2

Both solutions are invalid, exactly for the reasons you give - you're not separating them properly. Correct would be:

Business Logic

$customStylesheets = [];
$internalpath = "/internal/path/style.css";
if (!file_exists($internalpath))
  throw new Exception("Couldn't find style.css in " . $internalpath);
$customStylesheets[] = RewriteToExternal($internalPath);

Presentation

<?php foreach($customStylesheets as $stylesheet) : ?>
    <link href="<?=$stylesheet ?>" rel="stylesheet" type="text/css">
<?php endforeach; ?>

This way the business logic worries about what needs to happen, and the presentation about how to render it.

As for the general question: no, exceptions should never be thrown during rendering. Once the business logic has deemed a request acceptable, it should render completely and correctly. The presentation layer is not about decisions, just about output. If something fails 'exceptionally' at that point you screwed up the error checks in the BL layer.

To make these questions more obvious, don't use PHP as a template engine but grab a beautiful thing like Twig which forces you to keep your templates purely presentational. PHP as a template engine is just too big an invitation for some to separate things correctly.

Niels Keurentjes
  • 41,402
  • 9
  • 98
  • 136
  • 1
    The presentation layer can make decisions relevant to the presentation of course... Putting a check in the application layer for the existence of a CSS file as OP considers would move presentation logic into the application. The application should be concerned about business logic, and the presentation layer concerned about presentation logic, simple as that. – quickshiftin Dec 20 '13 at 22:42
  • 1
    It can make decisions, sure, that's why [conditionals are part of a template engine](http://twig.sensiolabs.org/doc/tags/if.html). That's absolutely not the same as 'throwing an exception', which is essentially the decision to 'not being able to continue rendering'. That decision should've been made before it was decided to **start** rendering. – Niels Keurentjes Dec 20 '13 at 22:46
  • +1. After [asking 1 year ago](http://stackoverflow.com/q/14532084) I only have one stylesheet. So, while your solution would be valid, that foreach would effectively be acting as an `if()`. However you remove/simplify a lot of the logic, so I will use something very similar to your answer. Also, thank you for suggesting Twig, but I prefer not to add another layer right now, I'll keep it in mind for the future though. – Francisco Presencia Dec 20 '13 at 22:47
  • 1
    It depends on the decision... A decision about the existence of a presentation file has _nothing_ to do with application logic. Template 'engines' are a bunch of extra cruft which cause more trouble than they're worth. PHP already is template engine by itself and exceptions are part of the language. Trying to take them away as part of a design decision of what the template layer should be is nonsense. – quickshiftin Dec 20 '13 at 22:49
  • @quickshiftin I'm not entering that discussion, the world has already decided for us through ASP.NET MVC's success, and the prevalence of template engines like Smarty and more recently Twig in professional PHP applications, that solid MVC separation with 'dumb' presentation layers are preferable. If you don't agree, so be it, but don't go pretending in topics like this one you know anything about true separation of concerns then, go write your single big PHP file which contains everything. Or [go read what the pros say](http://fabien.potencier.org/article/34/templating-engines-in-php). – Niels Keurentjes Dec 20 '13 at 22:52
  • Plenty of people, MVC frameworks and applications enjoy the _fact_ that PHP does templating out of the box. ASP.NET? I've heard of that, I think... Smarty et al are a big waste of energy and time, mainly because of the false sense of reality people grow on once they start using them, like throwing an Exception in the view layer has anything to do with separation of concerns... Throw an exception in a view, catch it in a controller, route to a generic error page. Cleanly separated concerns and completely _valid_ approach. – quickshiftin Dec 20 '13 at 22:58
-1

Why not throw Exceptions in the view layer? As long as you have a way to properly handle these exceptions in the application and ultimately display an appropriate 'Oops' type page ;)

quickshiftin
  • 66,362
  • 10
  • 68
  • 89