Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/EFX+Content+Management+System?V=26
QUERY_STRINGV=26
CONTENT_TYPE
DOCUMENT_URI/revision/EFX+Content+Management+System
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.69.59.196
REMOTE_PORT57312
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR3.145.83.150
HTTP_CF_RAY87f4708fe8581090-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_CF_CONNECTING_IP3.145.83.150
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

Body


Error

Unknow state transition: LINE -> END

-code

1

-level

0

-errorstack

INNER {returnImm {Unknow state transition: LINE -> END} {}} CALL {my render_wikit {EFX Content Management System} {EFX is a Content Management System (CMS) written in Tcl. I wrote it because I
needed something to help my son's school maintain their events, news,
newsletters pictures (a process in which they previously employed Frontpage).

I took a look at Bricolage, and while it is really cool (plus it doesn't
require you to use any kind of app server or apache plugin -- it produces 
plain old HTML pages), I found its use of Mason cumbersome and I wasn't
ready to brush up on my Perl. Plus, its a really big system that is difficult
to install and master. (My target was a fairly moderate site of about 30-40 
pages plus 50 or so pictures.)

I am still working on the school website (and EFX), but I found EFX already 
quite useful.

EFX (so far) consists of
   * EFX engine - A template engine based on ideas behind Zope Page Templates (which I had the pleasure of helping to define back in 2000) where markup is embedded in XML (XHTML) attributes.
   * Navmenu - A Navigational tool that helps you build hierarchical navigational menus and map out your site.
   * Story - A simple news content management tool that allows users to just put text files (with a title and date line) in a directory for inclusion into the website.
   * Calendar - An event management tool that presents a calendar UI interface to an events page.

The EFX engine is about 450 lines of Tcl that uses [TclXML] to parse and
operate on XML documents to produce XHTML pages. It is the most interesting
part of the system. Here are just a few of the commands it exposes inside
of XML element attributes:

   * efx:eval="command" - Evaluates command. Eats element and children. No output.
   * efx:eval_r="command" - Evaluates command.  Replaces element with result of the command.
   * efx:subst="" - Substitutes commands/variables in children. Outputs current node and children.
   * efx:onlyIf="expression" - Evaluates expression (with ''expr''). If true, outputs element and children. If false, eat element and children.
   * efx:foreach="var|command" - Iterates var over result of command, processing children (which may contain additional efx commands) until var is {}.
   * efx:processFile="input_file args" - Process additional XML files.

''Commands'' can be any Tcl expression. All commands and variables are
evaluated within a common Tcl namespace.

Each XML file is treated as a closure. 
Variable bindings introduced in each page is in effect until that page is finished (then any old bindings are restored). 
You can use efx:processFile to nest closures.

Okay, enough of that, how about an example?

Here is  a simple blog that I made in about 20 
minutes using the EFX toolkit: http://www.maplefish.com/todd/blog

I intend on improving the blog for doing RSS feeds and a few more features, 
but since it is a ''static'' site, no feedback/comment support is planned.

The source XML that generated all of the blog pages:

======
   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
     <head>
       <div efx:eval="source blog_settings.tcl"/>
       <div efx:eval="set BASEURL ."/>
       <div efx:eval="package require story"/>
       <div efx:eval="package require navmenu"/>
       <div efx:eval="navmenu::parse_file navmenu.map"/>
       <div efx:eval="set LinkMenu [navmenu::get Links]"/>
    
       <div efx:markBlock="MetaStuff">
        <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
        <meta efx:subst="" name="keywords" content="$BLOG_KEYWORDS"/>
        <meta name="generator" content="EFX"/>
        <style efx:subst="" type="text/css">@import url("$BASEURL/css/$BLOG_STYLESHEET");</style>
       </div>
       <title efx:subst="">$BLOG_NAME</title>
    
       <div efx:eval="set StoryDir ./entries"/>
     </head>
   <body>
     <div id="Header">
       <div efx:markBlock="BlogHeader">
         <div efx:subst="">$BLOG_HEADER</div>
       </div>
     </div>
   
     <div id="Content">
       <div efx:foreach="s|story::stories $StoryDir -max 10">
         <h4 efx:eval_r="story::title_as_ref $s"/>
         <small efx:eval_r="clock format [story::date $s] -format {%A, %B %d }"/><br />
         <p efx:eval_r="story::body $s"/>
         <hr efx:onlyIf="[llength $s]"/>
       </div>
     </div>

    <div id="Menu">
      <h4>Recent Entries</h4>
      <ul efx:foreach="s|story::stories $StoryDir -max 10">
         <li efx:eval_r="story::title_as_local_link $s">Title</li>
      </ul>
      <hr />
      <h4>Archives</h4>
      <div efx:eval="set MONTH_MENU [navmenu::make]"/>
      <!-- We make two passes, the first builds the menu of months;
       the second renders the month (which will need the menu of months
       for linking) 
       -->
      <div efx:foreach="pass| list make_menu render_month">
        <div efx:eval="set lns [story::stories $StoryDir]"/>
        <div efx:eval="set months [story::months $lns]"/>
        <div efx:foreach="month| set months">
           <div efx:eval="setl {MONTH_STORIES lns} [story::next_by_month $lns]"/>
           <div efx:eval="set THIS_MONTH $month"/>
           <div efx:onlyIf="$pass == {make_menu}">
             <div efx:eval="set MONTH_MENU [navmenu::add $MONTH_MENU $THIS_MONTH $THIS_MONTH.html]"/>
           </div>
           <div efx:onlyIf="$pass == {render_month}">
             <div efx:processFile="./month.xmlt ./$THIS_MONTH.html"/>
           </div>
        </div>
     </div>
     <div efx:eval_r="navmenu::render $MONTH_MENU {}"/>
     <hr />
     <h4>Links</h4>
     <div efx:eval_r="navmenu::render $LinkMenu $HERE"/>
    </div>
   </body>
   </html>


The ''blog_settings.tcl'' file just contains a few [set] commands 
to introduce BLOG_XXX variables:
======
   set BLOG_NAME {EFX Development}
   set BLOG_KEYWORDS {Todd Coram, EFX, templates}
   set BLOG_STYLESHEET {simple.css}
   set BLOG_HEADER {<h1> Todd's EFX Development Log </h1>}
======


Navmenu.map looks like:
======
   navmenu::menu Links {
        {EFX Development Log} index.html {}
        BREAK - -
        {Maplefish Home} http://www.maplefish.com {}
        {Almost Free Text} http://www.maplefish.com/todd/aft.html {}
   }
======


I'm hoping to do a code release by next week. 
If you are  interested in just looking at a raw code drop, check out
http://www.maplefish.com/todd/efx/efx.tar.gz (''not found'' as of 07 Jun 2007). 
The blog sources are at http://www.maplefish.com/todd/efx/blog.tar.gz

Comments are most welcome! -- [Todd Coram]
----
[jcw] - Interesting project!  I'm wondering why you are using XML as input format.  
Since only the output gets used, presumably, have you considered using Tcl as language to specify the whole website in?  
There are tools such as [xmlgen / htmlgen] which make it easy to generate properly formatted output.  
For a truly wicked digression from "normal" Tcl notation, see the end of [http://wiki.tcl.tk/3499], where I added an example that illustrates mixing structure and program flow.  Anyway, it's good to see more web-oriented software happening in Tcl, IMO - the web seems to be such a natural match for EIAS (everything is a string).

[Todd Coram] - The input format is really XHTML, so you can actually edit it with an HTML editor (at least one that respects attributes and namespaces). Also, because it is XML, I get validation (sort-of-syntax checking). One thing that I didn't show in my example is that in many cases you can actually put "dummy" values in between the efx'd elements so that your XHTML editor (dreamweaver, etc) will see actual content (which is then replaced by commands such as efx:eval_r). 
I shamelessly stole this idea from Zope Templates (which I worked on, so I guess it isn't exactly stealing ;-) Here is an example:
    <p efx:eval_r="set tcl_version"> Dummy text that will show up in an HTML editor, 
          but get replaced with results from "set tcl_version" </p>
will yield (when run through EFX to produce the final HTML):
    <p>8.4</p>

[Todd Coram] - Regarding EIAS and the Web... strangely enough, I chose to utilize Tcl in a rather FP/Lisp manner. EFX is very list oriented. Very lispy -- and I considered using Lisp to build this, but if I were to have used Lisp I would be missing out on the utility of Tcl!

''[jcw] - Ah, DreamWeaver, etc.  Ok, so these pages get created in a markup system, with logic tucked in.  Bingo, now I understand.''

[RLH] 2007-02-18: So do you want or need any help on this project?

----

[male] 2007-06-08 - Is there a current version somewhere to be used? 
On your, Todds, page I didn't find your EFX! [RLH] I emailed him and he said when he got the time he would tarball it up.

[tac] 2007-06-23 - I've put the source tarball and blog example up again: (http://www.maplefish.com/todd/efx/efx.tar.gz) and (http://www.maplefish.com/todd/efx/blog.tar.gz). 
It's very raw. I haven't touched the blog (or blog code) in a year, but the efx source is recent -- it is a sanitized snapshot of stuff running a small school's website. I removed a bunch of  unstable stuff (like the pop3 email retriever used to provide content for EFX to chew on) and the actual bash/Tcl code that starts the process running. It is what it is. I wish I had free time to work on it :-(

-----------------
!!!!!!
%| [Category CMS] | [Category Template] |%
!!!!!!} regexp2} CALL {my render {EFX Content Management System} {EFX is a Content Management System (CMS) written in Tcl. I wrote it because I
needed something to help my son's school maintain their events, news,
newsletters pictures (a process in which they previously employed Frontpage).

I took a look at Bricolage, and while it is really cool (plus it doesn't
require you to use any kind of app server or apache plugin -- it produces 
plain old HTML pages), I found its use of Mason cumbersome and I wasn't
ready to brush up on my Perl. Plus, its a really big system that is difficult
to install and master. (My target was a fairly moderate site of about 30-40 
pages plus 50 or so pictures.)

I am still working on the school website (and EFX), but I found EFX already 
quite useful.

EFX (so far) consists of
   * EFX engine - A template engine based on ideas behind Zope Page Templates (which I had the pleasure of helping to define back in 2000) where markup is embedded in XML (XHTML) attributes.
   * Navmenu - A Navigational tool that helps you build hierarchical navigational menus and map out your site.
   * Story - A simple news content management tool that allows users to just put text files (with a title and date line) in a directory for inclusion into the website.
   * Calendar - An event management tool that presents a calendar UI interface to an events page.

The EFX engine is about 450 lines of Tcl that uses [TclXML] to parse and
operate on XML documents to produce XHTML pages. It is the most interesting
part of the system. Here are just a few of the commands it exposes inside
of XML element attributes:

   * efx:eval="command" - Evaluates command. Eats element and children. No output.
   * efx:eval_r="command" - Evaluates command.  Replaces element with result of the command.
   * efx:subst="" - Substitutes commands/variables in children. Outputs current node and children.
   * efx:onlyIf="expression" - Evaluates expression (with ''expr''). If true, outputs element and children. If false, eat element and children.
   * efx:foreach="var|command" - Iterates var over result of command, processing children (which may contain additional efx commands) until var is {}.
   * efx:processFile="input_file args" - Process additional XML files.

''Commands'' can be any Tcl expression. All commands and variables are
evaluated within a common Tcl namespace.

Each XML file is treated as a closure. 
Variable bindings introduced in each page is in effect until that page is finished (then any old bindings are restored). 
You can use efx:processFile to nest closures.

Okay, enough of that, how about an example?

Here is  a simple blog that I made in about 20 
minutes using the EFX toolkit: http://www.maplefish.com/todd/blog

I intend on improving the blog for doing RSS feeds and a few more features, 
but since it is a ''static'' site, no feedback/comment support is planned.

The source XML that generated all of the blog pages:

======
   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
     <head>
       <div efx:eval="source blog_settings.tcl"/>
       <div efx:eval="set BASEURL ."/>
       <div efx:eval="package require story"/>
       <div efx:eval="package require navmenu"/>
       <div efx:eval="navmenu::parse_file navmenu.map"/>
       <div efx:eval="set LinkMenu [navmenu::get Links]"/>
    
       <div efx:markBlock="MetaStuff">
        <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
        <meta efx:subst="" name="keywords" content="$BLOG_KEYWORDS"/>
        <meta name="generator" content="EFX"/>
        <style efx:subst="" type="text/css">@import url("$BASEURL/css/$BLOG_STYLESHEET");</style>
       </div>
       <title efx:subst="">$BLOG_NAME</title>
    
       <div efx:eval="set StoryDir ./entries"/>
     </head>
   <body>
     <div id="Header">
       <div efx:markBlock="BlogHeader">
         <div efx:subst="">$BLOG_HEADER</div>
       </div>
     </div>
   
     <div id="Content">
       <div efx:foreach="s|story::stories $StoryDir -max 10">
         <h4 efx:eval_r="story::title_as_ref $s"/>
         <small efx:eval_r="clock format [story::date $s] -format {%A, %B %d }"/><br />
         <p efx:eval_r="story::body $s"/>
         <hr efx:onlyIf="[llength $s]"/>
       </div>
     </div>

    <div id="Menu">
      <h4>Recent Entries</h4>
      <ul efx:foreach="s|story::stories $StoryDir -max 10">
         <li efx:eval_r="story::title_as_local_link $s">Title</li>
      </ul>
      <hr />
      <h4>Archives</h4>
      <div efx:eval="set MONTH_MENU [navmenu::make]"/>
      <!-- We make two passes, the first builds the menu of months;
       the second renders the month (which will need the menu of months
       for linking) 
       -->
      <div efx:foreach="pass| list make_menu render_month">
        <div efx:eval="set lns [story::stories $StoryDir]"/>
        <div efx:eval="set months [story::months $lns]"/>
        <div efx:foreach="month| set months">
           <div efx:eval="setl {MONTH_STORIES lns} [story::next_by_month $lns]"/>
           <div efx:eval="set THIS_MONTH $month"/>
           <div efx:onlyIf="$pass == {make_menu}">
             <div efx:eval="set MONTH_MENU [navmenu::add $MONTH_MENU $THIS_MONTH $THIS_MONTH.html]"/>
           </div>
           <div efx:onlyIf="$pass == {render_month}">
             <div efx:processFile="./month.xmlt ./$THIS_MONTH.html"/>
           </div>
        </div>
     </div>
     <div efx:eval_r="navmenu::render $MONTH_MENU {}"/>
     <hr />
     <h4>Links</h4>
     <div efx:eval_r="navmenu::render $LinkMenu $HERE"/>
    </div>
   </body>
   </html>


The ''blog_settings.tcl'' file just contains a few [set] commands 
to introduce BLOG_XXX variables:
======
   set BLOG_NAME {EFX Development}
   set BLOG_KEYWORDS {Todd Coram, EFX, templates}
   set BLOG_STYLESHEET {simple.css}
   set BLOG_HEADER {<h1> Todd's EFX Development Log </h1>}
======


Navmenu.map looks like:
======
   navmenu::menu Links {
        {EFX Development Log} index.html {}
        BREAK - -
        {Maplefish Home} http://www.maplefish.com {}
        {Almost Free Text} http://www.maplefish.com/todd/aft.html {}
   }
======


I'm hoping to do a code release by next week. 
If you are  interested in just looking at a raw code drop, check out
http://www.maplefish.com/todd/efx/efx.tar.gz (''not found'' as of 07 Jun 2007). 
The blog sources are at http://www.maplefish.com/todd/efx/blog.tar.gz

Comments are most welcome! -- [Todd Coram]
----
[jcw] - Interesting project!  I'm wondering why you are using XML as input format.  
Since only the output gets used, presumably, have you considered using Tcl as language to specify the whole website in?  
There are tools such as [xmlgen / htmlgen] which make it easy to generate properly formatted output.  
For a truly wicked digression from "normal" Tcl notation, see the end of [http://wiki.tcl.tk/3499], where I added an example that illustrates mixing structure and program flow.  Anyway, it's good to see more web-oriented software happening in Tcl, IMO - the web seems to be such a natural match for EIAS (everything is a string).

[Todd Coram] - The input format is really XHTML, so you can actually edit it with an HTML editor (at least one that respects attributes and namespaces). Also, because it is XML, I get validation (sort-of-syntax checking). One thing that I didn't show in my example is that in many cases you can actually put "dummy" values in between the efx'd elements so that your XHTML editor (dreamweaver, etc) will see actual content (which is then replaced by commands such as efx:eval_r). 
I shamelessly stole this idea from Zope Templates (which I worked on, so I guess it isn't exactly stealing ;-) Here is an example:
    <p efx:eval_r="set tcl_version"> Dummy text that will show up in an HTML editor, 
          but get replaced with results from "set tcl_version" </p>
will yield (when run through EFX to produce the final HTML):
    <p>8.4</p>

[Todd Coram] - Regarding EIAS and the Web... strangely enough, I chose to utilize Tcl in a rather FP/Lisp manner. EFX is very list oriented. Very lispy -- and I considered using Lisp to build this, but if I were to have used Lisp I would be missing out on the utility of Tcl!

''[jcw] - Ah, DreamWeaver, etc.  Ok, so these pages get created in a markup system, with logic tucked in.  Bingo, now I understand.''

[RLH] 2007-02-18: So do you want or need any help on this project?

----

[male] 2007-06-08 - Is there a current version somewhere to be used? 
On your, Todds, page I didn't find your EFX! [RLH] I emailed him and he said when he got the time he would tarball it up.

[tac] 2007-06-23 - I've put the source tarball and blog example up again: (http://www.maplefish.com/todd/efx/efx.tar.gz) and (http://www.maplefish.com/todd/efx/blog.tar.gz). 
It's very raw. I haven't touched the blog (or blog code) in a year, but the efx source is recent -- it is a sanitized snapshot of stuff running a small school's website. I removed a bunch of  unstable stuff (like the pop3 email retriever used to provide content for EFX to chew on) and the actual bash/Tcl code that starts the process running. It is what it is. I wish I had free time to work on it :-(

-----------------
!!!!!!
%| [Category CMS] | [Category Template] |%
!!!!!!}} CALL {my revision {EFX Content Management System}} CALL {::oo::Obj6530138 process revision/EFX+Content+Management+System} CALL {::oo::Obj6530136 process}

-errorcode

NONE

-errorinfo

Unknow state transition: LINE -> END
    while executing
"error $msg"
    (class "::Wiki" method "render_wikit" line 6)
    invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
    (class "::Wiki" method "render" line 8)
    invoked from within
"my render $name $C"
    (class "::Wiki" method "revision" line 31)
    invoked from within
"my revision $page"
    (class "::Wiki" method "process" line 56)
    invoked from within
"$server process [string trim $uri /]"

-errorline

4