Skip to content

Instantly share code, notes, and snippets.

@chrisboulton
Created June 26, 2010 04:39
Show Gist options
  • Save chrisboulton/453780 to your computer and use it in GitHub Desktop.
Save chrisboulton/453780 to your computer and use it in GitHub Desktop.
Consider the following blocks of code from a controller and a view
whereby an existing comment is loaded from the database through a
model, and then a form is shown to edit the comment.
The form should handle th case where if one or more required
fields were left empty, the edit comment form should be shown again
with the values from the POST populating it instead of those from
the model.
The first example shows a typical approach of handling this
scenario.
Controller:
---
<?php
if($errors) {
if(isset($_POST['commentName'])) {
$template->assign('commentName', $_POST['commentName']);
}
if(isset($_POST['commentMessage'])) {
$template->assign('commentMessage', $_POST['commentMessage']);
}
}
else {
$template->assign('commentName', $comment['name']);
$template->assign('commentMessage', $comment['message']);
}
$template->display('edit_comment.html');
?>
--
View:
---
<form>
<p>
<label>
Name:
<input type="text" name="commentName" value="{{ commentName }}" />
</label>
</p>
<p>
<label>
Message:
<textarea name="commentMessage" value="{{ commentMessage }}" />
</label>
</p>
</form>
---
Seems like a lot of repeated code. How about we be smarter about it and:
* Name our form fields exactly how they appear in the database (or, are
returned from the model)
* Make use of our template system that lets us set an array to a template
variable, and either assign all of the posted values on an error, or
assign the comment from the database when there wasn't an error.
Yes?
Controller:
---
<?php
if($errors) {
$template->assign('comment', $_POST);
}
else {
$comment = Model_Comment::load(1);
$template->assign('comment', $comment);
}
$template->display('edit_comment.html');
?>
---
View:
---
<form>
<p>
<label>
Name:
<input type="text" name="name" value="{{ comment.name }}" />
</label>
</p>
<p>
<label>
Message:
<textarea name="message" value="{{ comment.message }}" />
</label>
</p>
</form>
---
So we've gone from 18 lines down to 11. And:
* Our code doesn't suck anymore. It's easier to read, and isn't conditional
and assignment hell.
* Our controllers are kept extremely simple. All they're doing is providing
the fundamental glue between the model and the view.
* When we add a new field to our model, all we need to do is update the
view to handle it. We don't need to touch the controller, and we shouldn't.
* Again, when we change an existing column, we just need to update the
view to handle it. No touching the controller.
* Implementing actual save/update logic also means there will be no assignment
hell. We can just load the model, and assign all of $_POST to it using
an appropriate setFromArray() method, instead of setting each field individually
($comment->name = $_POST['commentName'];)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment