I tried updating the old SmartyDocInfo class (changing public/private/protected to var, removing "public" from in front of functions, and changing the constructor to the name of the class) to work with PHP4, but got an internal server error (but only when I actually used rather than simply included the class--in my case to make a doc_raw to add CSS).

This class could be so useful in allowing the easy separation of content from formatting.

Though it's not much, I'd be willing to spring for $25 if you could successfully modify one of the files to get doc_raw working for PHP 4...It'd be especially helpful if a dedicated function could be added to avoid the need for adding {literal} and style tags too..

I have to use PHP 4 due to a bug in PHP 5 (handling multidimensional arrays of this length: $arr[$a][$b][$c]).

Sorry, I personally have no intention of porting to PHP4 (but feel free to do so -- it will require that you change things to properly deal with PHP4 object reference semantics and you will have to work-around PHP5 only object features that were used).

FWIW, I have no problem with $arr[$a][$b][$c] under PHP5 (I'm on 5.1.4 atm).

(I know the use of "key" is probably not the best (in case you wanted to allow more than one style doc_raw), but I was just piggy-backing on the existing framework to get it to work without messing things up too much)

I suppose a prefilter might be used to allow the use of curly braces within this special style doc_raw without {literal} tags, such that the curly braces would be converted into something else before the compilation stage (and then converted back to curly braces later by SmartyDoc, such as I have for the code mod above).

I also wonder whether you have considered using separate functions for each element. For example {body onload='blah();'} rather than {doc_info body='blah();'}. I think that may be more easy-to-remember/shorter.

As far as the PHP5 issue I mentioned in my last post, in case anyone wanted to know, the problem with $arr[$a][$b][$c] I had was due to offsets. In PHP5, you can't set $arr[$a][$b] = $var1; (if $var1 is a string, for example) and override it later with $arr[$a][$b][$c] = $var2, as it will treat the latter as $var1[$c] (and array-style offsets on strings are no longer allowed).

The functionality your script and these provide are all very broad feature sets, I think, and I would highly recommend these be added by default to a future version of Smarty, if at all possible. It is not of course just a niche who needs to have a doctype or CSS added!

I'd be happy to help somehow if I could, but if you're planning a new release sometime (and aren't adding it as you develop it to the wiki, etc.), maybe I shouldn't spend too much time on this now?

Also, do you have any thoughts on allowing users to generate some of the header data via a script and integrate it with the header data generated by SmartyDoc?

Hi.

How do you mean? By users do you mean template users? The SmartyDoc plugin API does much of that already and the {doc_raw} blocks allow similar from templates, but I suppose you have a different idea in mind?

Ahh..I'll have to take a look at the API then...But as far as doc_raw, if I add my own header, apply that to the template, and then use doc_raw also, I end up with two full headers (and bodies too, as I recall)

Also, since they were posted right after each other, you might not have noticed that I also just made a longer post previous to the last post (to which you did respond)...

Ah I see. Well, I can't really see how to stop someone from inserting a tag from within their templates. I suppose you could filter them and either remove the manually inserted tags and/or retarget their content into doc_info commands -- but I'm neither here-nor-there on that.

As for your css suggestion, its actually pretty good. I already support the "target" attribute which atm only accepts "head" and "body" but adding in targets for "style" and maybe "code" would be useful. Thanks for the idea, I'll see what I can do to accomodate it.

Ah I see. Well, I can't really see how to stop someone from inserting a tag from within their templates. I suppose you could filter them and either remove the manually inserted tags and/or retarget their content into doc_info commands -- but I'm neither here-nor-there on that.

Yeah, my bad. No need to filter them, I just wasn't aware of the API to add them in from the PHP side (which is more reasonable anyhow).

As far as additions to the code, thought I'd put what I could together in case it would be helpful.

1) About the doc_raw, in case one wishes only to use doc_raw, I believe this line in smarty_outputfilter_SmartyDoc:

2) In order to facilitate people converting to your script, I'd recommend changing the function (or adding an alias) of "displayDoc" to simply "display". This is discouraged below by boots

3) Below are a bunch of additions to allow relevant XML headers, XML declaration, XML stylesheet instructions, html and head definitions, as well as both doc_info and doc_raw inline styles and scripts (including the prefilter to deal with curly braces).

and the following (the XHTML namespace here (and below, if no doc_info is specified for 'html') is put as the default as it is likely to be changed, as it works with XHTML 1.0 and 1.1 (though it will probably not work with XHTML 2.0 when that comes out--the latter will also require additional attributes we can add at that time))

As xml:lang might be a more frequent need than say "dir", I put that as the renameto for these:

Also, instead of 'onload', I think adding 'body' with access to its other attributes (as taken from the W3C's page, including deprecated attributes) would be suitable, especially since one cannot use SmartyDoc along with body being added at the template level (as body is generated by SmartyDoc):

Maybe another 'optional' should be 'xml__space'? (language is deprecated, so I didn't see a need to add it and maybe should be removed from 'script' too? Even though something is required (like "type" in either of the above), it seems that they still get put under 'optional' too, so that they can be modified from the default.

Despite what I did above, for consistency, it might be clearer to rename what you have as "script" or "css" so that the inline versions will always have the same name as the tag itself (or always not). For example, "script" and "style" could always refer to internal uses, whereas the pseudonyms "code" and "css" could refer to external ones or vice versa. This would break backward compatibility though.

Later, such as after the meta declaration (which by the way, should probably be moved to the beginning of the head, because, as I recall, any encoding set there should precede the display of at least the title if not other head elements):
[php:1:aa4eb626bf] // process 'style' doc info
if (isset($_doc_info['style'])) {
$doc_source .= "{$indent}<style";
foreach ($_doc_info['style'] as $a=>$v) {
if ($a != '_content') {
if (!empty($v)) {
$doc_source .= " {$a}=\"{$v}\"";
}
}
}
$_doc_info['style']['_content'] = str_replace(array("[[", "]]"), array("{", "}"), $_doc_info['style']['_content']);
$doc_source .= ">/*<![CDATA[*/\n{$_doc_info['style']['_content']}\n/*]]>*/</style>\n";
}[/php:1:aa4eb626bf]

$callback = create_function('$matches', "return \$matches[1].str_replace(array('{', '}'), array('[[', ']]'), \$matches[3]).\$matches[4];"); // This approach is better than using preg_replace with the e modifier, since preg_replace auto-performs addslashes() which we do not want here

I haven't had a chance to test all of this yet (though my regexps in the previous post did work), but I can let you know if I do, and I do think it should work. Note: I have now tested all of the code (besides the server-side XSLT transforms) and it seems to be working fine.

Subsequent Additon:

And of course, in $DOCTYPES, under 'XHTML' (as I guess you probably were going to add already), append the following after 'Frameset':

whew: thanks for the code and comments. I'll have to digest it. I just wanted to comment quickly on the idea of renaming displayDoc to display -- the short answer is that I don't think it is a good idea. Without time to get into details, there is a significant difference between the two -- namely, it relies on fetchDoc() rather than fetch() (which display relies on) and the difference there is that fetchDoc() temporarily registers the output filter for the duration of its call. Now, if you ONLY ever call display() or fetch() once from your PHP script to render a completed document, then you might get away with having displayDoc() renamed to display(); on-the-other-hand, if you need to render pieces of the document separately and then have them stitched together in a final document producing call, then having access to both methods is important.

I'll try to get to your comments sometime this week. Please feel free to continue adding more details and thanks for your efforts with the code!

1) Html and Head were added to $doc_info_types to allow control of their attributes and of course, as a result, I also added relevant code subsequently when building the document (there is also an elseif added when this occurs to automatically include a namespace for XHTML documents if no doc_info was specified for 'html')
2) I made a note about how meta should probably precede title (and others?) so that any meta encoding can first take effect.

One thing I was pondering is the idea of automatically stitching linked css/js files and {doc_raw} items into single files (one for JS, one for CSS) based on the current compile_id and cache_id -- or perhaps to allow rules determine how/when files are stitched. (The idea there is to improve client performance by limiting the requests made for a given call while still permitting some client caching by not just simply stuffing everything into <script> and <style> elements in the <head>.)

One point first to clarify...I'm not sure I understand what you mean by "limiting the requests made for a given call" and why it seems you are contrasting that with (client) caching.

As far as compile_id and cache_id, it seems these can be null at some points in their lifetime (such as if there is no caching). For the sake of reusability (one benefit of external code/stylesheets), it seems it may be better not to inevitably append a (potentially variable) cache_id/compile_id, no? It seems that the template designer (or site developer) could conditionally supply the script/style generation with a URL (depending upon the section in which they appear), as I don't imagine the stylesheets would be varying as much as a cache would, no? (and if it were, the URL could be made variable by the designer/developer according to whatever conditions were desired). $smarty.template would seem to be handy to get the name of the current template to be used as at least a base. Maybe the PHP equivalent of $smarty.template ($smarty->_smarty_vars['template'] ?) could be used within the function to detect the template name if no file is specified.

As far as the general idea of it, I think it would be a real handy feature to have. It'd be very nice not to have to fumble around between different documents during the editing phase (i.e., just stuff it at the top of each template (if not out of necessity then to create a helpful convention)), yet have the benefit of allowing client caching of the external script/stylesheets. Despite the advantages of external sheets, if there are others out there like me, having the extra steps of creating, saving/uploading, and referencing can be a deterrent to adding this benefit.

Ok, now that I've tested this thing a bit more, I realized some bugs needed to be fixed (now altered in the code above) and the following also need to be changed:

I added the following array to be accessible from within addRaw and getRaw. I defined it as static since I didn't think this would be likely to be changed, but as I'm kind of new to OOP, I'm not sure whether this would in fact be suitable or not. I figured it should since we are not likely to dynamically change this information anywhere.

Change the addRawHeader, getRawHeader, addRawContent, getRawContent functions to these, with the target being passed with head (or body) as the default rather than only head (or body) being passed (as they probably were intended to have originally been anyways). This change is necessary now that the code has the style and script tags as possible (head) targets

Boots, what would you think if I added a link from your SmartyDoc wiki page to my own version of it--at least as an ongoing draft? This thread is probably not the best place for me to be revising my work continuously (though I really have it functioning now (as described above), at least).

Everything should be backwards compatible with the way you have it too, except I really think 'script' and 'style' should be aligned together to denote the same type (e.g., inline adds to the tags of those names) whereas 'code' and 'css' could be of the other type (e.g., external JS or CSS stylesheets). I am also eager to add functionality for the doc_raw contents, using the same nomenclature just described to make it optionally shuffled off to an external file, but if you think you may be able to catch up and get to that too, let me know (not to mention reconcile this with the additional work you said you had already done since your wiki posting).

Sorry for the lack of replies -- I hope I haven't slowed your progress I would in-fact prefer that you fork a different version at the wiki; that would give me some more time to find some cycles for the next release that I would like to make but have been unable to work on. I'm very glad you are still working on this and I have appreciated your many comments, code suggestions and additions. I'm sure to incorporate some of your ideas/code and if your work gets far enough ahead of my own, I'd be favourable to replacing my codebase with yours. Still, before that happens, I would appreciate having my code intact at the wiki so that I could both compare our versions and have a chance to do another release.

That said, if you do decide to create a new wiki entry, plesae do edit my wiki entry to cross-reference yours.

BTW, I'm glad that you decided on staying BC while I also appreciate that you may want to change some of the semantics to move forward. In the end, I don't think it is a good idea to diverge our codebases too much, so if I fall too far behind, you should probably just pick-up the reins and run with it.