[Bese-devel] Linking to resources (css, js) required by components

Marco Baringer mb at bese.it
Mon Aug 9 11:33:51 UTC 2004


Anthony Juckel <ajuckel at gmail.com> writes:

[sorry for the extremely long delay in responding to this]

--------------------------
linking to external files.
--------------------------

> First, why link to external files?  Two reasons:  1) To make the
> rendered page as clean (i.e. free of cruft) as possible and 2) to
> allow for browser caching of said pages.

  3) because you can't generate jpegs via yaclml code.

  4) because doing it well is not as easy it looks and so we should
     solve this issue within the framework.

this whole thing would be really easy if html allowed us to put
javascript and css links anywhere in the page, unfortunetly we have to
put css stuff in the body of the HEAD tag, and since we're supposed to
put js stuff there as well (we could get away with putting SCRPIT tags
more or lessall over the place though) we'll do that.

what this requires is that we be able, when rendering the HEAD tag, to
know _all_ of the components in the page. i had, up until now, avoided
making component nesting exlicit because i didn't really know what
kind of API i wanted, now we're going to have to do it. so, here's my
current idea:

(defgeneric MAP-SUB-COMPONENTS (component function))

(defmacro DO-SUB-COMPONENTS
    ((symbol component &optinal return-value) &body body)
  ...)

this will allow us to build something whereby each component can
decide to include some javascript or it's own special css file and
have the proper html put in the head section. this requires that
components define methods on MAP-SUB-COMPONENTS instead of just
calling RENDER-ON or <UCW:RENDER-COMPONENT (which they'll still have
to keep doing).

---------------------------------------------------------
so, how does a component state that it wants some js/css?
---------------------------------------------------------

personally i don't think this should done via options in the
defcomponent macro (i personally don't like the defcomponent macro as
it currently is. there's too much stuff there that you can't do
without it, unlike defclass which is just a convience wrapper for a
set of well defined mop functions).

what we should do is just define a few generic functions: RENDER-CSS
and RENDER-JAVASCRIPT (both with progn method combination) (names are
debatable). this is basically your RENDER-REQUIREMENTS method, but i'm
leaving the requires-external-resources option implict, if your
RENDER-JAVASCRIPT and RENDER-CSS methods don't do anything than you
don't need them (as you hinted we could do in your original mail). the
progn method combination means that subclassing components does the
Right Thing (TM).

what we'll end up having is a RENDER-REQUIREMENTS method which is
built on MAP-SUB-COMPONENTS and RENDER-CSS + RENDER-JAVASCRIPT. while
i've made this a bit more complicated than you'd originally suggested
i think the gain in flexibility is worth it, however you seem to have
a put a good deal of thought into this so i'd love to hear what you
think.

-----------------------------------------------------------------
so if we want to link to an extrenal .css file, how does the href
munging happen?
-----------------------------------------------------------------

i don't think there have been enough ucw apps developed to have a
concenus on this (even i am only at app number 3), that said here's
what i've done so far: i have a url path (like /ucw/docs/) mapped to a
particular directory (like /var/www/my-app/htdocs/) via apache. so if
i have a link href which points to foo.css then i put foo.css in
/var/www/my-app/htdocs/ and everything works. external images or
static html pages all use relative urls with the corresponding files
in /var/www/my-app/htdocs/. i even put the tal files in that directory
but since apache can't handle those directly i hove a yaclml
file-generator setup to look for files from /var/www/my-app/htdocs/.

let me put it this way: external resources are external to ucw, ucw
doesn't read them and can't hand them off to the client so ucw
shouldn't deal with locating them.

as far as i can tell you wanted *ucw-resource-root* so that you could
do:

(<:link :rel "stylesheet"
        :type "text/css"
        :href (concatenate 'string *ucw-resource-root* "tabbed-pane.css"))

i think what you really want instead of *ucw-resource-root* is
(application.url-prefix (context.application *context*)), or just
leave it relative if your directory structure is
flat. (*ucw-resource-root* would have to be a url path and not a local
file system directory path anyway).

--------------------------------
what about hooks on yaclml tags?
--------------------------------

this is a very cool idea.

however i don't think that a simple yaclml:register-hook function is
enough, particularly since i don't want to register a single hook for
every div or head tag that will ever be rendered. what could work is
a *yaclml-tag-hooks* special variable which you can bind to an alist
which will be checked (at run time) for extra handlers to
call. building a with-yaclml-hooks macro around this is trivial. this
gets you the hooks you want and limits them to certain piece of the
code if you want the global effect of yaclml:register-hook then just
set *yaclml-tag-hooks* to something.

however, what this would require is a lookup in an alist (or hash
table) _every_ time _any_ tag is rendered, is this really worth it?
should we compromise on a compile time effect or on allawing hooks
only on certian tags? (head or body for now)?

--------------------------------------------------------------
what about the butt ugly and inflexible tabbed-pane component?
--------------------------------------------------------------

Anthony Juckel is working on this and we're all eternally
gratefull. :)

p.s. - if anybody wants to mess around with ucw internals a bit
working on a particular component is a great way to start. currently
we have an extremly lame date-picker component, hint hint hint. the
range-view could use some work os well.

p.p.s. - i created a new branch (ucw--render-requirements--0.3) where
i'll be doing the refactoring and other edits required for these
changes. i'm going to keep working on the docs on ucw--dev--0.2 and
release 0.3 from that when the docs are ready.

-- 
-Marco
Ring the bells that still can ring.
Forget your perfect offering.
There is a crack in everything.
That's how the light gets in.
     -Leonard Cohen




More information about the bese-devel mailing list