By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,993 Members | 1,947 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,993 IT Pros & Developers. It's quick & easy.

Separation of logic, design and data

P: n/a
Friend, coders, fellow wage slaves, lend my your ears.

I believe that in a perfect world the design of a website (or feature
on a website) should be totally separated from its design and the data
it serves up. I'd like some suggestions on good ways to do this,
because in the real world it can be quite difficult.

For example, if I'm rummaging around in a MySQL database, the table
structure and the code that generates the SQL requests are often
interrelated. Restructure your table(s) and you have to update your
code accordingly.

Another, more serious issue is the separation of design from code. For
example, if I'm using tables to divide my pages into separate 'blocks'
(e.g. for a top bar, menu, content section, side bar, banner space,
etc.) then the structure of these tables and table cells are
interrelated with the program's flow: you set up a table or table
cell, do something that outputs data into that cell, close the cell
and/or table, and move on to the next cell to do something else there.
Removing or adding a cell will mean that the function(s) that output
data into that cell should or should not be called. Or the order in
which code is executed could be affected: if I want a page-wide top
bar cell followed by a menu column and a content window underneath, I
need to render the top bar table row first, spanning two columns, then
start a new table row in which I'd put the menu and content cell. But
if I want a menu bar all the way to the top of the screen and a top
bar cell followed by a content cell both to the right hand side of the
menu column, I need to render the menu cell first, spanning two rows,
and then progress to rendering the top bar and content cells.

One could of course take abstraction and modularization to extreme
levels (e.g. put every line of table-related code into a separate
template file and include that depending on program flow) but this
quickly increased both complexity and overhead to beyond what is
acceptable. Not to mention the fact that ideally one should not issue
function calls from within a content template file.

So how do real developers do this?

Regards,
Frank
Jan 23 '07 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Frank van Wensveen wrote:
I believe that in a perfect world the design of a website (or feature
on a website) should be totally separated from its design and the data
it serves up. I'd like some suggestions on good ways to do this,
because in the real world it can be quite difficult.
Keeping styling separate from the rest is smiple (sic): just do all your
layout, colour schemes, etc with CSS.

After that you've still got the problem of the fact that your code has to
do things in the correct order to output the page -- say, output HTML
header stuff first, then body stuff, then sidebar stuff, and finish with
some legalese and footer stuff. This can be solved using a template
engine. There are several available, though I can't say I like any of
them, I generally write my own template engine using the interface pasted
below. (Infact, I've only recently coded it as a proper PHP Interface,
earlier I used a standard class, which I would extend one or two methods
of.

This interface allows you to use (note the seemingly random order):

$t = new StdTemplate('Foo Bar');
$t->add_section('Foo', '<p>Foo</p>', 'foo',
StdTemplate::DIVISION_MAIN, 2);
$t->add_section('Bar', '<p>Bar</p>', 'bar',
StdTemplate::DIVISION_EXTRA, 3);
$t->add_section('Foo Bar', '<p>The life of Foo Bar</p>', 'foobar',
StdTemplate::DIVISION_HEAD, 1);
$t->add_script('/js/prototype.js');
$t->add_meta('Author', 'Me', FALSE, array());
$t->add_filter(new SpellCheckFilter(),
StdTemplate::DIVISION_MAIN | StdTemplate::DIVISION_EXTRA);
$t->add_section('Baz', '<p>Baz</p>', 'baz',
StdTemplate::DIVISION_EXTRA, 3);
$t->output();

which might output this:

<html>
<head>
<title>Foo Bar</title>
<meta name="Author" content="Me">
<script type="text/javascript" src="/js/prototype.js"></script>
</head>
<body>
<div id="head">
<div class="section" id="foobar">
<h1>Foo Bar</h1>
<p>The life of Foo Bar</p>
</div>
</div>
<div id="main">
<div class="section" id="foo">
<h2>Foo</h2>
<p><span class="spelling" title="Fool?">Foo</span></p>
</div>
</div>
<div id="extra">
<div class="section" id="bar">
<h3>Bar</h3>
<p>Bar</p>
</div>
<div class="section" id="baz">
<h3>Baz</h3>
<p><span class="spelling" title="Bat?">Baz</span></p>
</div>
</div>
<div id="foot">
</div>
</body>
</html>

Anyway, interface follows. Implement this interface and you'll be
happy. :-)

<?php

/**
* @author Toby Inkster <de******@tobyinkster.co.uk>
* @copyright Copyright &copy; 2007, Toby Inkster
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public Licence
* @version 1.0
*/

/**
* The Template interface is a standard interface that you must implement
* if you would like to create a new template for Demiblog. In addition,
* your template class must define the following constants. (PHP does not
* allow constants to be defined within a template.)
*
* DIVISION_HEAD = 1
* DIVISION_MAIN = 2
* DIVISION_EXTRA = 4
* DIVISION_FOOT = 8
* (You may define up to four custom divisions with values 16, 32, 64
* and 128.)
* FULL_HTML = -1
*
* The StdTemplate class supplied with DemiBlog outputs a page with roughly
* the following structure (it may vary, depending on HTML flavour):
*
* <!DOCTYPE ...>
* <html>
* <head>
* <title>...</title>
* <meta ... /><!-- etc -->
* <link ... /><!-- etc -->
* <script src="..."></script><!-- etc -->
* </head>
* <body>
* <div id="page">
* <div id="head">##</div>
* <div id="body"><div id="main">##</div><div id="extra">##</div></div>
* <div id="foot">##</div>
* </div>
* </body>
* </html>
*
* where locations marked with a double-hash (##) can be filled with zero or
* more content panels. This structure should be adequate for expressing most
* site layouts and should provide enough id and class hooks to hang most CSS
* designs onto.
*
* In the case where it does not prove sufficient, you have two options:
*
* 1. Keep the existing StdTemplate, but write a filter to modify its
* output (using, for example, regular expressions). The filter
* can be attached to the existing template using its add_filter()
* method.
*
* 2. Write a new template class, implementing the Template interface.
* Use the existing StdTemplate as a guide -- simply extending the
* existing template is probably sufficient. You will probably want
* to modify the output() method.
*/
interface Template
{
/**
* Add a section to the template with a particular ID and Title. Add
* it to a particular division or divisions.
* @param string $title Title of section.
* @param string $body Body of section. This should be in the correct
* flavour of HTML. The template will not attempt to rewrite it.
* @param string $id HTML ID of section. The template will protect
* against multiple sections with the same ID.
* @param int $to_division Division(s) to add to.
* @return bool Success.
*/
public function add_section ($title, $body, $id, $to_division, $heading_level);

/**
* Filter for sections. An object with interface TemplateFilter must
* be supplied. Filters are not applied until $this->output() is called.
* @param Object $object Filter object.
* @return bool Success.
*/
public function add_filter (TemplateFilter $object);

/**
* Adds a META element to the template's document HEAD.
* @param string $name META name.
* @param string $content META content.
* @param bool $is_http_equiv Replace "name" attribute with "http-equiv".
* @param Array $more_attributes Extra attributes for META element.
* @return bool Success.
*/
public function add_meta ($name, $content, $is_http_equiv, $more_attributes);

/**
* Adds a LINK element to the template's document HEAD.
* @param string $rel LINK relationship.
* @param string $href LINK destination.
* @param string $type LINK MIME Type.
* @param Array $more_attributes Extra attributes for META element.
* @return bool Success.
*/
public function add_link ($rel, $href, $type, $more_attributes);

/**
* Adds a SCRIPT element to the template's document HEAD.
* @param string $src Script file.
* @return bool Success.
*/
public function add_script ($src);

/**
* @return bool HTML Flavour.
*/
public function get_flavour ();

/**
* @return string Finished page.
*/
public function output ();
}

/**
* The TemplateFilter interface is an interface for defining filters that
* act on templates and may modify their output. Filters can apply to the
* whole finished page, or just to specific sections within it. Examples of
* uses for filters:
*
* - Gzip finished pages.
* - Highlight search terms.
* - Expand abbreviations.
* - Remove/replace deprecated markup.
*
* The list is endless. (Well, obviously not the list above, as that has only
* four items, and certainly ends. But possible applications for output filters
* are infinite.)
*/
interface TemplateFilter
{
/**
* Determines suitability of this filter to a section, based on
* section position and ID.
* @param int $to_division Section position.
* @param string $to_division Section position.
*/
public function should_apply ($to_division, $id);

/**
* @param string $title Title to be filtered.
* @param string $body Body to be filtered.
* @return Array array(filtered title, filtered body)
*/
public function apply ($title, $body);
}

?>
--
Toby A Inkster BSc (Hons) ARCS
Contact Me ~ http://tobyinkster.co.uk/contact

Jan 23 '07 #2

P: n/a
Frank van Wensveen wrote:
Friend, coders, fellow wage slaves, lend my your ears.

I believe that in a perfect world the design of a website (or feature
on a website) should be totally separated from its design and the data
it serves up. I'd like some suggestions on good ways to do this,
because in the real world it can be quite difficult.

For example, if I'm rummaging around in a MySQL database, the table
structure and the code that generates the SQL requests are often
interrelated. Restructure your table(s) and you have to update your
code accordingly.

Another, more serious issue is the separation of design from code. For
example, if I'm using tables to divide my pages into separate 'blocks'
(e.g. for a top bar, menu, content section, side bar, banner space,
etc.) then the structure of these tables and table cells are
interrelated with the program's flow: you set up a table or table
cell, do something that outputs data into that cell, close the cell
and/or table, and move on to the next cell to do something else there.
Removing or adding a cell will mean that the function(s) that output
data into that cell should or should not be called. Or the order in
which code is executed could be affected: if I want a page-wide top
bar cell followed by a menu column and a content window underneath, I
need to render the top bar table row first, spanning two columns, then
start a new table row in which I'd put the menu and content cell. But
if I want a menu bar all the way to the top of the screen and a top
bar cell followed by a content cell both to the right hand side of the
menu column, I need to render the menu cell first, spanning two rows,
and then progress to rendering the top bar and content cells.

One could of course take abstraction and modularization to extreme
levels (e.g. put every line of table-related code into a separate
template file and include that depending on program flow) but this
quickly increased both complexity and overhead to beyond what is
acceptable. Not to mention the fact that ideally one should not issue
function calls from within a content template file.

So how do real developers do this?
Hi Frank,

Toby gave a nice response + examplecode.
I just want to add a fairly simple way to achieve the same: includefiles.

If you combine css with seperate files, you gain large flexibility when it
comes to changing layout, etc.
For example: If you have a navigationbar with many links (for admin eg),
just include a file that contains them.
You can simply include it above every page that uses it.
If you need to add/change anything, you have just one place to check.
Same goes for footers, or other parts of html.

It is easy to build, and easy to understand, and easy to implement, and easy
to change. :-)

Disclaimer: I am not claiming this approach is better than some
template/parsing engine. It is just another way to approach the subject.

Regards,
Erwin Moller
>

Regards,
Frank
Jan 24 '07 #3

P: n/a
Erwin Moller wrote:
Frank van Wensveen wrote:
>Friend, coders, fellow wage slaves, lend my your ears.

I believe that in a perfect world the design of a website (or feature
on a website) should be totally separated from its design and the data
it serves up. I'd like some suggestions on good ways to do this,
because in the real world it can be quite difficult.
---SNIP
>
Hi Frank,

Toby gave a nice response + examplecode.
I just want to add a fairly simple way to achieve the same: includefiles.
--- SNIP
Disclaimer: I am not claiming this approach is better than some
template/parsing engine. It is just another way to approach the subject.
One template engine worth a look is smarty ( http://smarty.php.net ) gives
good separation of source php and markup html

IanR

--
homepage http://narian.org.uk
Jan 24 '07 #4

P: n/a
Frank van Wensveen wrote:
>
For example, if I'm rummaging around in a MySQL database, the table
structure and the code that generates the SQL requests are often
interrelated. Restructure your table(s) and you have to update your
code accordingly.
Exactly. The database and the code are not only interrelated, they are
married, or perhaps they are blood brothers, they can never be separated.
The code has to know about the structure of the tables.

There are two solutions to making this manageable. The historical solution
was the use of library code and data dictionaries. When OO mania came
along we got involved in the Viet Nam of software engineering: ORM.

I have tried both and found the classical solution to be far more practical.
The real difference in approach is that the classic solution requires a
little abstract thinking, while the ORM approach leads to a lot of ad-hoc
table-by-table coding.
--
Kenneth Downs
Secure Data Software, Inc.
(Ken)nneth@(Sec)ure(Dat)a(.com)
Jan 24 '07 #5

P: n/a
Erwin Moller wrote:
For example: If you have a navigationbar with many links (for admin eg),
just include a file that contains them.
You can simply include it above every page that uses it.
If you need to add/change anything, you have just one place to check.
Same goes for footers, or other parts of html.
But, in your example, if you have include("nav-links.html") scattered
about on many pages, but you want to move your navigation links from,
say, the top of the page to the bottom, then you need to change each file
that includes it. With mine, you only change one file.

The method you describe above is how I started using PHP, but as you start
building progressively more complicated sites, it eventually begins to
show its weaknesses. I started there, and now I'm here at my Template
interface solution, and I went through several different techniques on the
way. I'm sure at some point in the future I'll see the weaknesses in my
current technique and move on to something even better, though I'm not
sure what that might be.

Ian mentioned Smarty. I've investigated that too, but found it lacked what
I needed out of a template engine. Smarty looks handy for when there are
large invariable chunks of HTML that need to be used on many pages, and a
handful of variables that just need to be slotted into them. It's not for
me though.

--
Toby A Inkster BSc (Hons) ARCS
Contact Me ~ http://tobyinkster.co.uk/contact

Jan 24 '07 #6

P: n/a
Kenneth Downs wrote:
Exactly. The database and the code are not only interrelated, they are
married, or perhaps they are blood brothers, they can never be separated.
The code has to know about the structure of the tables.
Well, "the dream" is to build as little database information into the code
as possible, and have it infer as much as it can by querying the database
itself. But there's a limit to how much can be done in this area.

--
Toby A Inkster BSc (Hons) ARCS
Contact Me ~ http://tobyinkster.co.uk/contact

Jan 24 '07 #7

P: n/a
Someone wrote:
The database and the code are not only interrelated, they are
married, or perhaps they are blood brothers, they can never be separated.
The code has to know about the structure of the tables.
This is true in the general relational tables case, but not in all
cases.
Html is inherently hierarchical. It can be modelled and stored in
hierarchical structures, where each
node in the hierarchy represents a widget or div or paragraph in the
page,
and each such node can be adorned with a node_type attribute that
permanently ties it to a particular display behavior.

If you work with two *semi-mirror-image* hierarchies: one for defining
page layouts
and one for defining the data that gets pasted into its matching layout
hierarchy,
then it's possible to make a semi-automated system that works from a
point
and click editor, rather than the keyboard of a programmer.

Each page-type display hierarchy may have many data sets that can be
pasted
in, to make an arbitrary number of page instantiations for that layout.

To make each page the code loops through both hierarchies, pasting data
into
nodes in the layout, and then renders each node by default behavior.

When a system works that way you do not have to change anything about
the display code when the data changes. All you need is a point and
click
editor that creates hierarchical display definitions and the mirror
image
data sets to paste into the displays. Once you have the editor, you
never need the programmer again.

In other words you have a form that creates a form that defines a
layout
as a hierarchy. The rest can happen--forever--as drag and drop and
click.

Jan 24 '07 #8

P: n/a
It is time for PHP to come up with something like Java's Hibernate &
Spring. They was a PHP implementation of Java's Struts, but it has not
been modified in a year or so. I think we all may need to join in the
party to help out.

On Jan 24, 8:12 am, "pittendrigh" <Sandy.Pittendr...@gmail.comwrote:
Someone wrote:
The database and the code are not only interrelated, they are
married, or perhaps they are blood brothers, they can never be separated.
The code has to know about the structure of the tables.This is true in the general relational tables case, but not in all
cases.
Html is inherently hierarchical. It can be modelled and stored in
hierarchical structures, where each
node in the hierarchy represents a widget or div or paragraph in the
page,
and each such node can be adorned with a node_type attribute that
permanently ties it to a particular display behavior.

If you work with two *semi-mirror-image* hierarchies: one for defining
page layouts
and one for defining the data that gets pasted into its matching layout
hierarchy,
then it's possible to make a semi-automated system that works from a
point
and click editor, rather than the keyboard of a programmer.

Each page-type display hierarchy may have many data sets that can be
pasted
in, to make an arbitrary number of page instantiations for that layout.

To make each page the code loops through both hierarchies, pasting data
into
nodes in the layout, and then renders each node by default behavior.

When a system works that way you do not have to change anything about
the display code when the data changes. All you need is a point and
click
editor that creates hierarchical display definitions and the mirror
image
data sets to paste into the displays. Once you have the editor, you
never need the programmer again.

In other words you have a form that creates a form that defines a
layout
as a hierarchy. The rest can happen--forever--as drag and drop and
click.
Jan 24 '07 #9

P: n/a
Toby Inkster wrote:
Erwin Moller wrote:
>For example: If you have a navigationbar with many links (for admin eg),
just include a file that contains them.
You can simply include it above every page that uses it.
If you need to add/change anything, you have just one place to check.
Same goes for footers, or other parts of html.

But, in your example, if you have include("nav-links.html") scattered
about on many pages, but you want to move your navigation links from,
say, the top of the page to the bottom, then you need to change each file
that includes it. With mine, you only change one file.
True.
That is the weakness of using includes for HTML pieces.
It can be overcome by using an include in the include, like this:
in header of page:
<?php include 'headerstuff.php'; ?>

and at bottom:
<?php include 'footerstuff.php'; ?>

And then put in the headerstuff.php another include:
[headerstuff.php:]
<?php include 'contactinformation.php'; ?>

If set up like that you can easily move/modify from header to footer by
editting/moving contactinformation.php from headerstuff.php to
footerstuff.php.

But I must admit that approach tends to get a little messy. :-)
And also you must decide beforehand WHERE you want your possible includes.

Personally I prefer the simplicity of includes over the use of a
templatesystem.

I think your template approach is much better if you have to maintain a
website that changes a lot. Then the original extra overhead pays back in
10-fold I expect. :-)

just my 2 cent..

Regards,
Erwin Moller
>
The method you describe above is how I started using PHP, but as you start
building progressively more complicated sites, it eventually begins to
show its weaknesses. I started there, and now I'm here at my Template
interface solution, and I went through several different techniques on the
way. I'm sure at some point in the future I'll see the weaknesses in my
current technique and move on to something even better, though I'm not
sure what that might be.

Ian mentioned Smarty. I've investigated that too, but found it lacked what
I needed out of a template engine. Smarty looks handy for when there are
large invariable chunks of HTML that need to be used on many pages, and a
handful of variables that just need to be slotted into them. It's not for
me though.
Jan 25 '07 #10

P: n/a
Toby Inkster wrote:
Kenneth Downs wrote:
>Exactly. The database and the code are not only interrelated, they are
married, or perhaps they are blood brothers, they can never be separated.
The code has to know about the structure of the tables.

Well, "the dream" is to build as little database information into the code
as possible, and have it infer as much as it can by querying the database
itself. But there's a limit to how much can be done in this area.
The completion of "the dream" is to have the library know nothing about any
specific app which is easy if you have a complete dictionary. This is what
we have done, our libraries have zero knowledge of any specific database.
Here is how it works.

We use a tool to build/upgrade databases out of a dictionary. When the build
is complete, it takes the dictionary and generates a bunch of include files
for PHP that contain associative arrays describing each table. Any
function that needs to access a database loads the relevant arrays and
determines whatever it needs to know about the table(s).

In terms of the UI, the gen-spec equation falls usually in favor of
specialization, meaning it pays in the business sense to write specific
files for specific apps that "know" about tables and columns, because that
is what makes that app valuable to a paying customer.

--
Kenneth Downs
Secure Data Software, Inc.
(Ken)nneth@(Sec)ure(Dat)a(.com)
Jan 25 '07 #11

This discussion thread is closed

Replies have been disabled for this discussion.