Gossamer Forum
Home : Products : Gossamer Links : Version 1.x :

Is it possible to use: %>

Quote Reply
Is it possible to use: %>
I tried to use the following line in add.html:
<%include <%filename%>%>

In add.cgi, I tried to pass the value of <%filename%>:
&site_html_add_form ({ filename => 'abc.html', Category => $category, %in }, $dynamic)

Although abc.html is there, I always got this error message:
Can't find file: ....../abc.html

Is there any way to do this? Thanks!
Quote Reply
Re: Is it possible to use: %> In reply to
If the <%include%> tag allows nested tags, the problem may be the path.

The <%include%> assumes the file is in the templates directory, so you'd need to pass a path in with the filename.


Quote Reply
Re: Is it possible to use: %> In reply to
Path is not the problem.
The error message was like:
Can't find file: /../cgi-bin/admin/templates/abc.html
It is the correct path.
Quote Reply
Re: Is it possible to use: %> In reply to
Check your path again:

Can't find file: /../cgi-bin/admin/templates/abc.html

says, start at the root, go up one (impossible) and then enter the directory with the absolute path of:

<one level above root>/cgi-bin/admin/templates/abc.html

Unix would have a hard time doing that.

Windows might attempt it, but give bizzare results.

------------------
POSTCARDS.COM -- Everything Postcards on the Internet www.postcards.com
LinkSQL FAQ: www.postcards.com/FAQ/LinkSQL/










[This message has been edited by pugdog (edited January 13, 2000).]
Quote Reply
Re: Is it possible to use: %> In reply to
I believe the problem has nothing to do with the path.
The key is in sub parse:
Code:
# Parse includes, do this first so that the includes can include
# template tags.
$temp =~ s#$begin\s*include\s*(.+?)\s*$end#
if (exists $self->{'inc'}{$root}{$1}) { $self->{'inc'}{$root}{$1}; }
else {
if (open (INC, "${$self}{'ROOT'}/$1")) {
$self->{'inc'}{$root}{$1} = join ("", <INC> );
close INC;
$self->{'inc'}{$root}{$1};
}
else {
"Can't find file: ${$self}{'ROOT'}/$1";
}
}
#goe;

If I change:
Code:
if (open (INC, "${$self}{'ROOT'}/$1")) {
to:
Code:
if (open (INC, "/../cgi-bin/admin/templates/$1")) {

I still got the same error.

However; if I change it to:
Code:
if (open (INC, "/../cgi-bin/admin/templates/abc.html")) {

The problem was solved. abc.html was correctly parsed.

So I think the problem is that <%filename%> can't be correctly parsed.

This question has been asked in other forums . But I can't find any good answer.
www.gossamer-threads.com/scripts/forum/resources/Forum3/HTML/003987.html
www.gossamer-threads.com/scripts/forum/resources/Forum3/HTML/002664.html

The reason I want to use <%include <%filename%>%> is:
If I can use it, all my cgi scripts(such as add.cgi and modify.cgi) can call the same sub, for example, site_html_standard_form.
While in sub site_html_standard_form, there will be:
Code:
my $output = &load_template ('standard.html', {
While in standard.html, there will be (similar to your idea):
Code:
<%TOP%>
..
<%include <%filename%>%>
..
<%BOTTOM%>

So, in add.cgi, it will pass add.txt to <%filename%>;
in modify.cgi, it will pass modify.txt to <%filename%>.

Thus, only one sub (site_html_standard_form), one template (standard.html) and other .txt file(the different parts) are needed.

It will reduce the size of HTML_Templates.pm and all the templates and be easy to modify the templates.






[This message has been edited by Fortune (edited January 13, 2000).]
Quote Reply
Re: Is it possible to use: %> In reply to
While there might be a benefit to one subroutine call, part of the control over the templates _IS_ due to having a routine for each block of the program.

I purposely avoided removing them in my original proposal. My original thoughts were to simplify the maintennance of the site and redundant code that had to change with minor look-and-feel changes to the site. By keeping the various load template calls in separate subroutines, you've blocked the program off into sections with control over each of the routines, and the ability to override them easily. Not every routine would really know what to do with each set of passed parameters, and as the program gets more complex, it might cause problems.

A data/control array puts all the parameters in one easy to see area. The various subroutine calls make it easy to see the flow of the program. When you start replacing too many parameters that don't really improve the quality of life (so to speak) you can start making things harder (code harder to maintain) than easier (site easier to maintain).

If you look at what I suggested, you could do pretty much the same thing by editing the array, and setting a few additional parameters to be passed in the data array.

That might eventually simplify the subroutines to one call, and a hash reference, but it needs to be done in stages.
It looks like we are tackling the problem from opposite ends.

As for the code:
Code:
if (open (INC, "/../cgi-bin/admin/templates/$1"))

Again, that is an IMPOSSIBLE path.

It says start at the top, go one level up, to heaven, then start looking for the file.

I've got to believe that that _is_ a problem, since that path doesn't exist.

I didn't think nested tags were allowed, but your first post seemed to indicate that the nesting was being properly parsed:

ie - you got the error message:

Code:
Can't find file: ....../abc.html

which would indicate that the filename _was_ being passed, but that the system couldn't find it ... that's a PATH problem.

I haven't tried to do this, I've been working on the user features first. File uploads are next. Maybe Alex has an answer, but the only time a path of:

/../some/other/path

would work, is if it's being appended to another path such as:

$Links{'build_root_path'}/../some/other/path

But the links variable needs to be defined absolute to the file system root.

"open" is a system call, and all it does is assign the filehandle INC to the path you give it. The path you are passing is invalid.

Unless I'm missing something really, really basic, or "open" has been overloaded in some way, that has to be a problem.

My initial reaction was that nested tags like <%include <%filename%>%> wouldn't work, but as I indicated, YOU indicated that part was working, so it has to be a path. Looking at the code fragment, there is no attempt to parse the <%filename%> tag
Quote Reply
Re: Is it possible to use: %> In reply to
The problem is that the parser first go thru the includes, and then it changes the <%codes%>
So, when it include the file, there is no file <%filename%>
Thats why you receive an error
Quote Reply
Re: Is it possible to use: %> In reply to
Hello, pugdog,

The path I mentioned before:
Code:
/../cgi-bin/admin/templates/$1
actually was:
Code:
$LINKS{admin_root_path}/templates/$1
I omitted part of it.

It will only take you 5 minutes to try it.
You will understand what I mean.

Hello, tmoretti,

I know that. I just want to know how to modify sub parse to make it work.
Quote Reply
Re: Is it possible to use: %> In reply to
What you could do is put another pre-parser in before the <%include%> parser, that looks for <%include <%tag%>%> (or any nested tags) and first expands the nested tags. Once the nested tags are expanded, you can send it to the <%include%> pre-parser to include the files, then to the parser to do the parsing.

If you are only doing it for <%include%> then you could impose the rule that the nested tag had to be a filename defined in in the filenames array, which is picked out and sent to the subroutine as FILENAME=>'template.include'

If your preparser hit that, it checks the passed hash for the FILENAME tag, and if it finds it, uses it.

Is that close?
Quote Reply
Re: Is it possible to use: %> In reply to
I did it.
In sub parse, I added the following code right before:
# Parse includes, do this first so that the includes can include..

Code:
my $begin2 = $self->{'begin2'} &#0124; &#0124; quotemeta('<<');
my $end2 = $self->{'end2'} &#0124; &#0124; quotemeta('>>');
$temp =~ s/$begin2\s*(.+?)\s*$end2/
if (exists $self->{'vars'}{$1}) {
ref ($self->{'vars'}{$1}) eq 'CODE' ?
&{$self->{'vars'}{$1}}($self->{'vars'}) : $self->{'vars'}{$1};
}
else { "Unkown Tag: $1"; }
/goe;
Quote Reply
Re: Is it possible to use: %> In reply to
Sorry I missed this thread earlier! You are indeed right in that includes are included first, so what you had wouldn't work. The fix is ok as well, except that you suffer a slight performance penalty for having to parse the page twice (once before and once after).

Cheers,

Alex
Quote Reply
Re: Is it possible to use: %> In reply to
Hey! You could fix that performance penalty by rewriting the "official" routine to check the <%include%> tag for a tag before processing it <G>

Or, what about using a <%include %filename%%> construct, so that the parser is still looking for the next %>, but if it hits a %text% block before a %> that becomes an include file not a literal. That could be handled by the file include routine, not the parser, even, by assuming it's a file name, then checking to see if it's a %filename% or just filename.

This is somewhat of a special case, since the include tag is already looking for a replaceable parameter, we only need to let the file open routine know whether it's a literal or variable, and if a variable, where to get the name to open.