Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Bespoke HTML, CSS, JavaScript with CGI 4

Status
Not open for further replies.

1DMF

Programmer
Jan 18, 2005
8,795
GB
I've been using PERL for many years and write all my HTML code by hand using a zillion backslashes.

On a few of my posts people have said "Why are you writing HTML, use the CGI module, you'll never have to write a line of HTML code again"

one claimed they write all theire CSS menu's, forms, webpages etc.. with the PERL CGI module.

can someone explain to me how, how can the CGI module know how to draw your menu, without you using HTML, this doesn't make any sense to me.

Can anyone help explain how all this is done with the CGI module without writing a single line of HTML?

Thanks 1DMF



"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
I've been playing with a test script and template but keep getting this error
HTML::Template->new() : Cannot open included file : file not found.
but the file does exist ?

any ideas.

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Try setting the file from the physical location of it on the system instead of a URL.
 
ahh - good thinking batman!

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Code:
print header;
doesn't work, is this part of the Template Module?

Isn't that part of the CGI module, I can't see anywhere in your example where you put "use CGI;", is it worth invoking CGI just to print the header , isn't it easier and more efficient to just use
Code:
print "Content-type: text/html\n\n";

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
ok I've got it working(well kind of) using my print content-type method, now I have this problem

the output is wrong, this is what I get....
FirstName : Joe
LastName : Bloggs
FirstName : Joe
LastName : Bloggs
here is the PERL
Code:
#!/usr/bin/perl

######################
# Set Error Trapping #
######################

use CGI::Carp qw(fatalsToBrowser warningsToBrowser); 
#use warnings;
use strict;

######################
# Use Globals Module #
######################
use Memglobs;    

#######################
# Use Template Module #
#######################
use Template;

my (@section_data, %data);
    
$data{'ID'} = 1;        
$data{'FirstName'} = "John";
$data{'LastName'} = "Smith";
    
push @section_data, \%data; 
    
$data{'ID'} = 2;        
$data{'FirstName'} = "Joe";
$data{'LastName'} = "Bloggs";  
    
push @section_data, \%data;
            
my $template = HTML::Template->new(  type => 'filename',
                                   source => DIR_TO_CGI . '/temptest.htm',
                        die_on_bad_params => 0) or die "Cannot open temptest.htm Template file: $!";

$template->param( 'section' => \@section_data, );
              
print "Content-type: text/html\n\n";

print $template->output;
and here is the HTML
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>SSPL Home Page</TITLE>
<META NAME="KEYWORDS" CONTENT="underground, dance music, music, dance, underground music, dj, djs, electronica, computer music, clubbing, raves, rave, record, records, cd, cds, jungle, techno, drum, bass, house, hardcore, garage, hip hop"> 
<META NAME="DESCRIPTION" CONTENT="Dedicated to underground music enthusiasts, listen to tunes, order tunes, sign/view guestbook, play games, cool links, chat room, charts and votes system, listen to our radio or post messages to our message board discussion forum, love music?, if yes, why not visit our web site !!!">
</HEAD>
<BODY>
<tmpl_loop name="section">
<div id="id<tmpl_var name="ID">">
    FirstName : <tmpl_var name="FirstName">
    <br>
    LastName : <tmpl_var name="LastName">    
</div>
<br>
</tmpl_loop>

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
d'oh of course, you push into the array the reference to the hash, I then change the content of the hash, but the memory reference doesn't change, so when I push the second hash to array as it's a reference, it places the same reference so it is an array of the same reference, thus when looping I get the same output which is what the hash was last changed to, in my "REAL" working version the looping data will be an array of hashes so I actually won't have this problem.

See sometimes a test environment, doesn't work, then if i'd used a live record set, but then I wouldn't have understood what was going on as well as I do now!

Many thanks for your help, this Template is going to take a little while to get used to, especially as i'm used to putting the HTML within an IF statement in the PERL, for END_ROW functionality, now I need to create a specific row identifier and place the IF in the HTML with the tmpl_if tag, but I understand it's usage, which is the main thing.

Oh there is one last question, how do I use the template tags like html comments, which I read in the overview was possible, that way you can validate your HTML with w3c as normal.

do you simply place !-- in the fromt and -- at the end of the template tag?, how does that work for dynamic content like my example using the ID param to dynamically create individually "Id'ed" Divs.

is w3c still going to complain that you cant have
Code:
<div id="id<tmpl_var name="ID">"></div>

as this isn't valid HTML? any ideas

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Wow, I need to sleep less I guess. This'll teach me to fall asleep while watching hockey. heh Lots of questions and answers to give. I'll try to break the answers down in the order they were asked as best I can.

Test code:
Yeah, the problem was that you weren't creating a new hash for each set of data you want to pass into a loop. Not a big deal, but it does make for a frustrating time.

Commenting Template tags:
HTML::Template documentation said:
If you're a fanatic about valid HTML and would like your templates to conform to valid HTML syntax, you may optionally type template tags in the form of HTML comments. This may be of use to HTML authors who would like to validate their templates' HTML syntax prior to HTML::Template processing, or who use DTD-savvy editing tools.

<!-- TMPL_VAR NAME=PARAM1 -->

As for adding in tags to make your div IDs valid, that might be a little more tricky. You'll probably have to validate you code before adding in those tags just due to the way the validators work. I know, not the best answer, but...

Hope this helps!

- George
 
how do you create single scalar variables for merging.
Code:
$template->param( 'section' => \@section_data, );

this requires you to place a <tmpl_loop> tag doesn't it, to then get to the <tmpl_var name="varname">, you see I have "system variables" which now I need to export to the HTML template, like so...

Code:
my (@globals; %globals);
    
$globals{'url_to_domain'} = URL_TO_DOMAIN;
push @globals, \%globals;                    

my $template = HTML::Template->new(  type => 'filename',
                                   source => DIR_TO_DOMAIN . '/commissions.htm',
                        die_on_bad_params => 0) or die "Cannot open commissions.htm Template file: $!";

$template->param( 'globals' => \@globals, );
              
print "Content-type: text/html\n\n";

print $template->output;

does the above then require me to loop 'globals', before i can use <tmpl_var name="url_to_domain">.

I just want to create a standard variable that can be used anywhere in the template , hows that done.




"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
ok - worked it out, standard vars are created
Code:
$template->param( 'url_to_domain' => URL_TO_DOMAIN );

I now have the <> problem, as you said, but if i can't get my template validated because of the chevrons, then i'm looking at ditching this template module, it's not going to bring me any closer to geting HTML that is away from my PERL and validates on W3C, i know it comments
If you're a fanatic about valid HTML ....

sorry but that's no different than saying if your a fanatic about valid PERL, CSS, PHP, ASP or anything else.

or are they admitting they haven't used VALID and ACCEPTABLE PERL code for this module, i'm sure that's not the case, so therefor i expect to be able to get valid HTML using this module!, not a fanatic, just want to end the woe and cries from people about not having valid, wellformed, symantically correct code, shouldn't we all be striving for that?

i've tried
Code:
&lt;tmpl_var NAME='url_to_domain'&gt;
in the template but that doesn't seem to work, any ideas how I can escape the chevrons correctly, or even hack the module to look for the special codes instead of the chevrons!





"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
ok, it seems it "DOES" validate, phew, but I get warnings...
Below is a list of the warning message(s) produced when validating your document.

Warning Line 8 column 36: character "<" is the first character of a delimiter but occurred as data.

is this OK ?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
I don't see why it wouldn't be ok... Don't forget, you could also write your tags as such:

Code:
<!-- tmpl_var name="url_to_domain" -->

Which will validate properly. The only time you "MAY" have an issue is where you're dynamically assigning style sheet information. I've always been one to validate my HTML after the page was rendered by the script, not before, so the validation apps on w3c.org will never see the code, just the resulting HTML. This way, I know that there isn't a problem anywhere in the code or resulting output.

- George
 
yeah, I hear ya, though I was planning on validating both!, to make really sure it's valid.

I really appreciate all the help, i'm sure i'll need some more before i'm done, so have a great day and will speak to you soon, no doubt tomorrow, when i get my head into the real stuff.

I already know i'm going to ask about the best way to create the output arrays, but it can wait, i've devised my own way, will post once complete and you can then hopefully tell me if i'm wrong or right and give further advice.

many thanks,
1dmf

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
I have a concern!, on another thread someone made the following comment
I guess you would never write anything in ASP then, since it freely mixes HTML and VBScript. Personally, I don't see how you can possibly develop a robust web application without mixing HTML and server-side coding.

As you know i'm trying to separate my code, now someone has suggested that anything that separates serverside & HTML is not robust, is this true?



"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
I'm completely stuck now, I don't understand how you nest loops.

I have this template and I have created the parameters for the template, but it doesn't work....
Code:
<div><div><div style="display:none;"><ul id="imenus0" style="width:95px; z-index:3;">
        <!--tmpl_loop name="month"-->
            <li  style="width:95px;"><a name="<tmpl_var name='month'>" style="text-decoration:none;"><!--tmpl_var name='month'--></a>
                <!--tmpl_loop name="year"-->
                    <div><div style="width:65px;top:-18px;left:80px;"><ul style=""><li><a name=""><!--tmpl_var name='year'--></a><div><div style="width:140px;top:-18px;left:50px;"><ul style="">
                        <!--tmpl_loop name="stat"-->
                            <li><a name="<tmpl_var name='docid'>" onclick="getAjax('<tmpl_var name='url_to_https'>/commissions4.cgi','FA=VW&requireduser=$user&DOC=<tmpl_var name='docid'>','<tmpl_var name='period'>')">Period Ending <!--tmpl_var name='period'--></a></li>
                        <!--/tmpl_loop-->
                    </ul></div></div></li>
                <!--/tmpl_loop-->
            </ul></div></div>
        <!--/tmpl_loop--> 
        </li></ul><div style=\"clear:left;\"></div></div></div></div>

any ideas?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Ah, again with me being behind... One of these days it will stop snowing here and I'll be able to get out here at a decent hour.

ASP - I disagree with that statement for a few reasons, one being that ASP was made to intermingle code and HTML. If you want to completely separate your design work from the back end code (J2EE and JSPs takes this approach as well, so Perl is not alone) to give the ability for someone that doesn't know the language to make visual changes to the pages, then this really is the solution to do. You can do some things (and this increases every day) with CSS, but even it has it's limitations depending on how the underlying HTML code is structured. If you want to be able to turn this over to someone else to change the design of the site, then you really want to keep the code out of that person's hands.

OK, off my high horse. On to the problem you have. To nest loops, all you need to do is pass in an array reference into the outer loop. Something like the following:

Code:
my @month = qw|January February March April May June July August September October November December|;
my @years = qw|2005 2006 2007 2008 2009 2010|;

my @month_loop;
foreach my $month (@months) {
    my (%data, @year_loop);
    $data{month} = $month;
    foreach my $year (@years) {
        my %year_data;
        $year_data{year} = $year;

        push @year_loop, \%year_data;
    }
    $data{years} = \@year_loop;

    push @month_loop, \%data;
}

Not the best example, but it's simple. Let me know if this still isn't very clear.

- George
 
no this doesn't make sense, the loop- is 3 nested and I already have arrays with hashes, and i put them into the template with param, this is all ok.

but apparently to use nested loops you have to create the data nested in the param-> command.

I'm really having difficulty understanding this and have given up for today, i'm getting to frustrated with myself to achieve anything on this project at the moment.

i've picked it up in the perl forum under this thread...
thread219-1165628, where i have pasted the two peices of code, which might make more sense to you.

thanks,
1DMF

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top