

![]() | Start a set with this search |
![]() | Include this search in one of my sets |
![]() | Exclude this search from one of my sets |
![]() | Permalink to these results Paste this link in email or IM: |
| Atom feed for tracking future search results Paste this URL into your reader: |
28 messages in net.sourceforge.lists.courier-sqwebmail[sqwebmail] Re: Spelling and other te...| From | Sent On | Attachments |
|---|---|---|
| oth...@freeshell.org | Dec 21, 2004 1:57 pm | |
| Brian Candler | Dec 28, 2004 3:11 am | |
| Sam Varshavchik | Dec 28, 2004 4:16 am | |
| Paul L. Allen | Dec 28, 2004 11:32 am | |
| oth...@freeshell.org | Dec 28, 2004 7:45 pm | |
| oth...@freeshell.org | Dec 28, 2004 8:45 pm | |
| oth...@freeshell.org | Dec 28, 2004 9:02 pm | |
| Paul L. Allen | Dec 29, 2004 3:28 am | |
| oth...@freeshell.org | Dec 29, 2004 11:39 am | |
| Paul L. Allen | Dec 29, 2004 1:18 pm | |
| oth...@freeshell.org | Dec 29, 2004 2:34 pm | |
| Paul L. Allen | Dec 29, 2004 4:50 pm | |
| oth...@freeshell.org | Dec 29, 2004 9:08 pm | |
| Brian Candler | Dec 30, 2004 1:10 am | |
| Brian Candler | Dec 30, 2004 2:29 am | |
| Paul L. Allen | Dec 30, 2004 9:56 am | |
| Paul L. Allen | Dec 30, 2004 12:15 pm | |
| oth...@freeshell.org | Dec 30, 2004 2:39 pm | |
| oth...@freeshell.org | Dec 30, 2004 3:14 pm | |
| Paul L. Allen | Dec 30, 2004 4:07 pm | |
| Brian Candler | Dec 31, 2004 2:40 am | |
| Laurent Wacrenier | Dec 31, 2004 3:00 am | |
| Paul L. Allen | Dec 31, 2004 3:41 am | |
| Brian Candler | Dec 31, 2004 4:11 am | |
| Pawel Tecza | Dec 31, 2004 4:47 am | |
| Laurent Wacrenier | Dec 31, 2004 5:22 am | |
| Brian Candler | Jan 1, 2005 4:45 am | |
| Brian Candler | Jan 1, 2005 5:17 am |

![]() | Permalink for this message Paste this link in email or IM: |
![]() | Permalink for this thread Paste this link in email or IM: |
| Atom feed for this thread Paste this URL into your reader: |
| Subject: | [sqwebmail] Re: Spelling and other templates (Was: stale processes and m17n) | Actions... |
|---|---|---|
| From: | Paul L. Allen (pl...@softflare.com) | |
| Date: | Dec 30, 2004 9:56:38 am | |
| List: | net.sourceforge.lists.courier-sqwebmail | |
Brian Candler writes:
On Wed, Dec 29, 2004 at 09:18:47PM +0000, Paul L. Allen wrote:
ISTM that gettext is unnecessary overhead, because sqwebmail already has three-quarters of such a subsitution mechanism built in.
ISTM that gettext would be unnecessary overhead even if sqwebmail didn't have three-quarters of a substitution method built in.
I'm sure you could map S590 to "Login" directly in gettext. The difference would be that should the particular language translation be missing that string, the user would actually see "S590" on the web page, instead of the English string.
If a particular string translation is missing from the chosen language then the default language should be used. If the default language file is also missing that string then you will see S590 or nothing at all or "???" or whatever the code puts there in such cases. BTW, the default shouldn't be English, it should be a build-time option choosing from whatever language files exist. So it should use whatever language the user chooses, if that file and particular string is available, if not is uses the build-time default, if not then it falls back to English (I'm not being a language chauvinist here, that's the only language file Sam will keep current in a release), if not then some error message generated by the code (probably just the substitution number so you can figure out which one is missing).
Another way would be to abandon templates and have all the html generated on the fly by the code. That would eliminate the template substitution step. But then you lose the ability to easily change the look and feel of the page - you have to hack code instead of html and most people who are good coders are not good at page design/layout (and vice versa).
I believe we should move towards the other extreme - all HTML in the templates and none in the code.
I agree entirely. But I covered that case merely for completeness. You COULD remove some overhead by abandoning templates but there is a big penalty to pay in terms of making it very hard to customize.
What I'm thinking of is a recursive substitution mechanism.
There are many ways of skinning that cat. See various perl templating systems for examples.
[...]
Now, the rendering of the login page would simply call [#HTML_LOGINPAGE#], and as it was expanded, other strings would be dynamically sub-expanded.
I'm not sure that this is a good idea. Ideally a template should look as much like the final result as possible, to the extent that you could feed it into Nightmareweaver to edit it. Dynamic expansion would make it very difficult for html designers to see what they're going to end up with. I think it has to be as close to WYSIWYG as possible.
Note that [!ERROR!] is a special case. It triggers some C code which expands either to an empty string or to [#ERROR_INVALID#] or [#ERROR_EXPIRED#], depending on the context.
This is the one case where WYSIWYG has to be abandoned - conditional inclusion. But even then the page designer can see where the text is going to fall, even though the width is wrong.
Translations would simply override some of the strings (those containing text). Alternate templates would override other ones (those containing HTML or HTML fragments).
Again, I think HTML fragments is a bad way to go. Imagine a designer viewing one of the default pages, saving the source and editing that source to achieve the desired look. The templates should be as close as possible to that. Anything else complicates matters far too much for most page designers. They can cope (just) with [#S581#] meaning "User" and move it around the page using their favourite HTML editor, they won't cope with [#fragment1#] meaning include this fragment of HTML from elsewhere.
HTML designers could use the snippets as macros, for example using them for things like the rounded corners [#CORNERTL#] could eliminate a lot of duplication within the templates, and also make it easier to tweak them (e.g. a local override to replace four strings with blank text if you want to get rid of all the corners)
You're thinking like a programmer, not like a web page designer. We could do this all in TeX. That's a particularly arcane language but is capable of the task. Then we could tell the page designers that if they want corners they just need to \expandafter\cornermacro{image.gif} and they'll love us for it. Actually, they won't. They want templates that look like the final thing so they can edit them and see, in a browser, how it is going to look. You and I can expand macros in our heads and anticipate how things are going to look; they want to actually see the result. Yes, you can build a test box for them to try their templates on but they'll still hate you for not letting them use their usual tools in the way they normally use them to edit a page and see how it looks immediately. I know this from personal experience.
Since sqwebmail is a daemon now, it can read in all the strings into RAM at startup time and apply local overrides etc.
It may be better to load on demand. There's not much point loading Chinese translations if nobody needs them.
The sources can be plain text files; no need to convert them into any indexed representation (e.g. dbm).
Since the index for translations will be essentially numbers, loading them into an array is not only adequate, it's sensible. You're not going to need an inverse lookup so no need for a hash in memory or a dbm.
I think there should be local overrides for strings, stored separately from the sqwebmail templates so they are not lost when you upgrade version.
Good point. Say a local_lang directory in which you put only the language files you need and they contain only the strings you've changed rather than a full set. If a string is matched in the appropriate local_lang file then use it otherwise use the standard one.
Now, I think the simple mechanism I've outlined would do pretty well, but it could be made more sophisticated.
Like I said, there are many ways of skinning this cat.
One option is to make it use XML syntax. Instead of [#FOO#] you can have <span id='FOO'/> which expands to the text alone.
Or you could use comments. I've seen plenty of templating systems that used <!--#substitute$foo--> or similar. And they annoy the hell out of our page designers because they can't see anything on the page. So the last time I knocked up a templating system I used {!-#substitute$foo-} which is of a form that would never appear in ordinary text but is visible. Actually, I also used <!--#loopstart$foo--> for loops because you do want those markers to be invisible because they mess up tables if visible.
So your idea is clever, but it violates the principle of having the template look as closely as possible to the page that gets output.
Now, the other thing to recognise is there will be a lot of special cases in code where fragments conditionally embed other fragments which embed other fragments. Let's take something like the folder list:
[!FOLDERLIST!] <!-- currently [#F#] I believe -->
Now, in the new scheme this would trigger some C code which in turn triggers more HTML fragments: it may trigger [#NODELPERM#] or [#NOINSERTPERM#]
otherwise it goes onto to some more steps. First it generates [#FOLDER_TABLESTART#] which contains <table width="100%" border="0" cellspacing="0" cellpadding="4"> <tr class="folder-index-header"> <th align="center">[#NUM#]</th><th> </th><th>[#DATE#]</th> <th>[#FROM#]</th><th>[#SUBJECT#]</th><th>[#SIZE#]</th> </tr>
then it goes into a loop generating repeatedly [#FOLDER_TABLEROW#]
Again, I believe this to be a bad idea from the viewpoint of those who are going to edit the templates. The way to do a loop is more like:
Stuff on the page before the folder list. <!--#loopstart$folder--> <tr class="folder-index-header"> <th align="center">[#NUM#]</th><th> </th><th>[#DATE#]</th> <th>[#FROM#]</th><th>[#SUBJECT#]</th><th>[#SIZE#]</th> </tr> <!--#loopend$folder--> Stuff on the page after the folder list.
This makes the template look as close as possible to the page that gets output, albeit with only one row.
For conditionals I've used <!--#foo?-->foo is true<!--#foo:-->foo is false<!--#foo;--> and the equivalent {!-#foo?-}... I allowed both because there are times when it should be visible and times when it shouldn't (when it encloses a row in a table).
and there are there are various special case tags which make sense in this context: [!ODDEVEN!] inserts 1 or 2 for alternate messages
Agreed. Although I usually call it rowclass because it's used to select a class for alternating rows in a table, and I usually expand it to odd or even in <tr class=[!ROWCLASS|]>. Unless you have a different use in mind.
[!ENTRY_START!] inserts either [#ENTRY_START_READ#] or [#ENTRY_START_UNREAD#] depending on whether the message is read or not [#ENTRY_START_READ=<span class="read-message">#] [#ENTRY_START_UNREAD=<strong class="unread-message">#] [!POS!] inserts the current message number, and so forth.
Better as things like <tr class="[#read-or-unread#]"> applied to rows. The idea, yet again, is to keep it as much like the real thing as possible.
I think that would work just fine and has the huge advantage of removing all the HTML code fragments from the C source.
Removing all HTML fragments from the code has to be the way to go.
However it involves a lot of cross-referencing to see which bits of HTML are inserted where,
So does your clever substitution scheme. The stuff might all be in one file but a page designer wouldn't be able to tell what it does just by opening it in a browser.
and you still need to look at the C source to find out the logic for the magic bits, such the names of the HTML fragments which [!ENTRY_START!] might generate,
This is why [!ENTRY_START!] is a bad idea.
An alternative would be if the HTML fragments were nested, rather than cross-referenced. What I am thinking of is this. [...] Now, the magic goes with the "id=..." binding.
No, it has to be as unmagic as possible. It's a clever idea, the sort that appeals to programmers, but it makes the template look even less like the final thing. Think "monkey with Nightmareweaver" not "coder."
I don't think this necessarily gives you any more power than the previous tag-substitution example, but it means all the HTML is in one place and has the same nested structure that the output will have. Perhaps the explicit nested tag-substitution is simpler to code and understand for sqwebmail developers though.
Maybe, but unless it's something a page designer who isn't a coder can see and understand by looking at the template in a browser, it's not really an improvement. You can't avoid the fact that looped structures like the folder list will have only one row but you can make that row look like the real thing and in the 'right' place. When the guy edits it he'll see it's wrapped in loopstart/loopend comments and realize that wherever on the page he wants the folder list to appear he has to move that row and its enclosing comments. Well, maybe he won't realize, but when it doesn't work he'll look more closely at the original and figure it out or read the FAQ.
-- Paul Allen Softflare Support







