Ok, guys I have read and digested (and been grateful for) all of the above comments. I know that from your end the probability that I have created something worth looking at is very low, and that in all likelyhood it appears I have simply reinvented a perfectly good wheel.
Appearances can be deceptive.
Yes there are real similarities between what I have and the systems mentioned above, but none of those do what my system does, and I have looked at them.
All I can say is that I feel immensely constrained when working with any other language, and I would love to find an existing wheel which does exactly as my wheel does, but it doesn't seem to exist.
Now from what I have given above it is difficult to explain why that is, because I haven't given you the whole story yet it was just an inroad, an attempt to start explaining something I don't know how to explain, and yet as a strong believer in the opensource principle, dearly wish to share with the world.
The only solution I can see right now, is to continue trying to explain what I have, and hope that I don't bore the pants off you guys before the picture becomes clear and you can objectively judge the merits of thing.
Ok, if your still with me, I will elaborate further...
The definitions of the tags are usually stored in a plugins folder, one file for each tag the filename corresponding to the tag name and containing the code to run for that tag.
I have about 50 definitions in all which cover just about everything I can think of, and typically as I move from project to project I don't make any changes to the core engine or the tag set.
So when I start a new project I simply build (or copy) an existing barebones template file accross, and then start building the pages. Thus I can have something up and running in minutes.
My implementation handles all the database level shash etc, leaving me free to simply design the tables, queries and UI. for a typical project I may not have to write any plugins or code at all, since all the functions needed are covered by the existing plugins and the unique method I found to stack them together in many different ways.
It is this "unique method" which is the bit I most want to share, since the rest of the framework I have built around it and indeed the plugins are just icing on the proverbial cake, and moreover it's a cake that needs refinement to improve efficiency.
I would LOVE it, if Template Toolkit or similar allowed me to use the "unique method", but it doesn't nor does any other system I can find.
My schema has very simple set of rules and 3 types of tag delimiters, which indicate process priority over child tags. This may seem arbitary but once you see the reasons for it, it becomes very useful.
Rule 1 : Child tags are computed prior to parent tags.
Rule 2 : The $result of the computation of a child tag, becomes the $data of the parent tag.
Rule 3 : Tags delimited by ( ) type brackets, are computed
prior to their children unless the child tags are also of the type ( ).
Rule 4 : Tags delimited by [ ] type brackets, are computed last.
Rule 5 : The system only computes tags which it recognises and are syntactically valid, whilst ignoring everything else.
So with those rules in mind consider this action page;
listing of /actions/default/main.aXML
<table width="50%">
(DB)
<query>
SELECT * FROM latestnews;
</query>
<mask>
<tr>
<td>
<d>news_title</d>
</td>
<td>
<d>news_headline</d>
</td>
<td>[link action="readnews"
newsitem="<d>news_id</d>"
]Read More...[/link]
</td>
</tr>
</mask>
(/DB)
</table>
Because the DB tag is of type ( ), it is computed prior to its child tags, and produces a list of news items and links.
Because the link tag is of type [ ], the links are processed last to become standard hyperlinks to the news items.
It's not a framework, I am not trying to plug a replacement to template toolkit etc, I am just trying to show you the "unique method" I found and why it saves me huge amounts of time and effort. In the length of time it has taken me to tap up this essay, I could of built a whole news system complete with validation and presentation etc, because I've already done the grunt work on previous jobs and now I can just mix and match the components using the simple rules to create endless variations.
| [reply] [d/l] [select] |
So with those rules in mind consider this action page;
What you have described looks like basic Template::Plugin::DBI or HTML::Mason, or AxKit... you created a standard set of templates/plugins/components/filters... for common tasks
I am just trying to show you the "unique method" I found and why it saves me huge amounts of time and effort....
Perhaps the reason it saves you time and effort is because you, the designer and implementor, know it well -- describes majority of software -- code-fire is hard to start , it requires lucky timing :)
| [reply] |
I don't understand; what is the handler for the DB tag actually passed? The raw text contained in it, <query>, etc. and all?
| [reply] [d/l] |
From my understanding it boils down to
$DB->($query, $mask)
Where query is sql and mask is a template, and $DB is a function that basically does
my $sth = $dbh->prepare($query);
$sth->execute;
$out = '';
foreach my $queryResult( $sth->fetchrow_hashref )
$out .= $mask->process( $queryResult )
}
return $out;
Except he chose delimiters to be different and significant -- which is why he had to use regular expressions to parse his xml-ish balanced tags, instead of using XML::Twig or HTML::Seamstress
To do the same in TT2, you create a template DB which uses Template::Plugin::DBI so you can write
<table width="50%">
[% MACRO mask BLOCK %]
<tr>
<td>
[% news_title %]
</td>
<td>
[% news_headline %]
</td>
<td>[% WRAPPER link
action = "readnews"
newsitem = news_id %]Read More...[% END # block test %]
</td>
</tr>
[% END # macro block mask %]
[% INCLUDE DB ## db calls macro mask, can be redefined
query=' SELECT * FROM latestnews; '
%]
</table>
query is a variable, mask is macro ( a template ) , and the template DB calls the macro mask, after defining variables based on database column names (presumably news_id, news_title, news_headline ) to populate mask
This works out of the box with TT2.
Sure, you have to define the MACRO mask before INCLUDE-ing the template DB, but that could be remedied by expanding the syntax so you can assign macros to a variable, or it could be implemented as a Template::Plugin or Template::View -- not a lot of work
| [reply] [d/l] [select] |