473,397 Members | 2,077 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

Separation of logic, design and data

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
10 2265
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
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
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
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
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
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Eric Veltman | last post by:
Hello everyone, I've posted this question before, but got no answer, so I'll try to reformulate the question, maybe it helps :-) By the way, this is not intended as the start of an ASP.NET...
13
by: Droolboy | last post by:
I'm trying to build a fairly small (max. 10 different pages) site using php, and it's becoming obvious that I need some kind of model view separation. Having done a few searches, I've come...
20
by: Griff | last post by:
Hi there I'm after some suggestions as to how one might best separate form and content in a normal run-of-the-mill web application. I'm sure whole bookshelves have been written on this, but I...
8
by: Jon Maz | last post by:
Hi, I'm facing a code-optimisation issue on an asp.net/vb.net/SQL Server 2000 project. A web page containing not much more than 3 DropDownLists is taking nigh on 6 seconds to load, because each...
7
by: Rob R. Ainscough | last post by:
I understand and implement the concept (as best I can), BUT what I would like to know -- how is it possible to completely remove the UI from business logic? "UI references business logic, but...
16
by: MS newsgroup | last post by:
I don't have clear reasons why we need business logic layer and data logic layer instead of having only data logic layer. Are there any good reasons for that?
15
by: Jay | last post by:
I have a multi threaded VB.NET application (4 threads) that I use to send text messages to many, many employees via system.timer at a 5 second interval. Basically, I look in a SQL table (queue) to...
29
by: Brad Pears | last post by:
Here is a simple OO design question... I have a Contract class. The user can either save an existing contract or they start off fresh with a blank contract, fill in the data and then save a...
2
by: robert.waters | last post by:
I am new to C#, and have written some code to update a textbox control on a form with the output from an external script. However, I am not sure if I have properly separated the user interface...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.