Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Parsing and Spewing CSS

by davemabe (Monk)
on Nov 14, 2000 at 21:50 UTC ( #41602=perlquestion: print w/replies, xml ) Need Help??

davemabe has asked for the wisdom of the Perl Monks concerning the following question:

I am building a mod_perl web site (who isn't?) and would like users to be able to customize as much of the style as possible. So here is my plan: create a default external style sheet with default settings and then use perl to query a database for a user's style settings and produce a <STYLE> element with all the individual customizations at the top of the html page. Is there an easier way to do this? Any obvious pitfalls? It looks like CSS::Parser would be the way to go. Anyone had experience with CSS::Parser that they would like to share?

Replies are listed 'Best First'.
Re: Parsing and Spewing CSS
by Fastolfe (Vicar) on Nov 15, 2000 at 00:50 UTC
    I might approach this differently. If all of the user preferences are going to be in a stylesheet, why not link an external style sheet (generated by a CGI script). That way you can use the same preferences on static content just as you can for dynamic content.
    <link rel='stylesheet' type='text/css' href='/cgi-bin/generate-css.pl' +>

      An additional advantage to this method is that the browser will cache the style sheet locally and reduce the number of calls to your server. Of course, this could be a bad thing if you were planning on changing the style sheet frequently, but in my experience that's pretty rare.

      Actually, I'd be interested in hearing about solutions to this as I've tackled this a completely different way in Mason:

      /* keys %head */ % foreach (keys %head) { <% $_ %> { font-size: <% $head{$_} %>pt; color: <% $colours{'head'} %> +; \ % if ($isNetscape) { font-family: <% $font_family %>; padding-left: 10px; padding-top: 10px +; \ % } else { margin-left: 10px; margin-top: 10px; \ % } } % } /* keys %text */ % foreach (keys %text) { <% $_ %> { font-size: <% $text{$_} %>pt; \ % if ($isNetscape) { color: <% $colours{'text'} %>; font-family: <% $font_family %>; paddin +g-left: 10px; \ % } % if (($isIE) && ($_ eq 'P')) { line-height: <% $line_height %>pt; margin-left: 10px; \ % } % if ($_ eq 'UL') { list-style-type: circle; \ % } } % } %head = ( 'H1' => $font_size + 6, 'H2' => $font_size + 4, 'H3' => $font_size + 2, 'H4' => $font_size, 'H5' => $font_size ); %colours = ( 'text' => '#FFFFFF', 'head' => '#99CCFF', 'link' => '#CCCCCC', 'vlink' => '#999999', 'alink' => '#99CCFF', 'list' => '#99CCFF', 'smalllist' => '#99CCFF', 'listheaders' => '#99FFFF', 'highlight' => '#FFFFFF', 'data' => '#FF9933' );

      I need clean this up a lot, but it was the way that (kind of) made sense to me when I was trying to build a style sheet that would adapt according to browser support/os/individual preferences...

        This brings up an interesting point. CGI scripts should never be cached by the browser. I believe most (all?) web servers, when serving up any CGI or dynamic (making use of SSI) content, will note a page with, like, an immediate Expires header, or some other mechanism to let the browser know that the page shouldn't be cached.

        What if you want data to be cached? Is the best way to accomplish this to emit an Expires header of our own? What about If-Modified-Since-qualified requests? Do we then have to process those, and emit the requisite 304 if no change has been made? In short, is there a module or better mechanism for scripts to participate in the expiration/caching process, or to at least override the server's default behavior of marking CGI-generated content as uncachable?

RE: Parsing and Spewing CSS
by little (Curate) on Nov 15, 2000 at 02:25 UTC
    Just in case you face a browser that doesn't support external stylesheets your script could decide whether to insert a link to a script that produces the stylesheet (as Fastolfe suggested) or to write the stylesheet within style tags directly into the document to deliver .
    You probably don't need to use CSS::Parser as you know the possible fields in your stylesheet template that can have values. So simply read from the template, let Text::Template fill in the vars for you (which you might get via DBI::CSV or DBI::* whatever is comfy for you)
    So all together with CGI.pm for the forms you need only "a needle" to put those parts together


    Have a nice day
    All decision is left to your taste
RE: Parsing and Spewing CSS
by extremely (Priest) on Nov 15, 2000 at 10:36 UTC
    I gotta say this is one place where the cgi "handler" trick is useful. If you are HTML::Mason'ing or other meta-content generator, this is even easier. just link the users stylesheet to a url like this:
    <LINK rel=STYLESHEET TYPE="text/css" href="/style/USERNAME.css"> # style is a CGI/handler in the main path

    Now when you generate the CSS code for them it "looks" like it's coming from a file and you can further spoof browsers into caching the data by sending the header:

    Last-Modified: Fri, 22 Sep 2000 19:24:17 GMT

    If you store a last changed date with the users prefs, you can make a cheesy HEAD/Conditional-GET that just grabs the change date and returns the 304 Unchanged response if the dates match. With just a little more work, the browsers cache the stylesheet and you beat up on your DB just a little less. That is a bandwidth and sanity win all the way around.

    There are a lot more tweaks you can throw at it. I've got a conditional handler laying about somewhere for Mason, I think. I started to do this very same thing but haven't yet bothered with customizability since I'm working real functionality on the site I'm doing.

    --
    $you = new YOU;
    honk() if $you->love(perl)

RE: Parsing and Spewing CSS
by Maclir (Curate) on Nov 15, 2000 at 06:16 UTC
    The only catch with using style sheets, is that Netscape's support of CSS1 (certainly Netscape 4, I have not tested the just released Netscape 6) is for all intents and purposes brain dead. While MSIE is not 100% compliant, at least it generally works with CSS as you think it should.
Re: Parsing and Spewing CSS
by darobin (Monk) on Apr 24, 2001 at 22:33 UTC

    This is fairly old but I just came accross it. I just wanted to add that I have experience with CSS::Parser: I wrote it. And I can tell you one thing about it, it s**ks real bad :(

    However, I've now released CSS::SAC, the next generation replacement which I hope is much better (I've also removed CSS::Parser from CPAN). If you still need to do some CSS parsing, that would be the thing to try. I'd be happy to help, and it definitely needs people to bang on it (the folk from www-style have already started, but there's never enough :)

    -- darobin -- knowscape 2 coming soon --

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://41602]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2021-10-23 15:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My first memorable Perl project was:







    Results (88 votes). Check out past polls.

    Notices?