Gossamer Forum
Home : Products : Links 2.0 : Customization :

Help! What does this shift code do?

Quote Reply
Help! What does this shift code do?
Anyone know what this code does?
_________
my $self = shift;
my $template = shift;
__________
It is in Template.pm and it seems to pick up passed data. But, not sure what and how to pass more data to this routine. Would this work if I added it below the above code?
___________
my $build_root_path = shift;
my $Category = shift;
my $ID = shift;
my $build_extension = shift;
_____________
As I want to pass the latter for a mod.

Also, if the shift is picking up the data. I wonder why not use my @data = @_? Is there a difference in these to statements.

Thanks
TimRyan



[This message has been edited by timryan (edited August 04, 1999).]
Quote Reply
Re: Help! What does this shift code do? In reply to
Ok,

How much do you know about 'default' variables???

my $self = shift;
my $template = shift;


Without looking at the code, but "thinking in Perl", the first line above would take the first element off the @ARGV array in the main program, and @_ array in any subroutine.

(It can also be passed a specific array, which it will pop the top element, and shorten the array by 1 each time it's called).

@ARGV is a 0 based array so $#ARGV is the position of the last element in the array, and $numelements = $#ARGV+1

Can't get more specific than that withou looking at where the code is, but is that in the "load_template" call?


The same should hold true for @_ in subroutines.




Quote Reply
Re: Help! What does this shift code do? In reply to
Thanks pugdog, that was good! And you are right it is in the "load_template" call.. I have been working on a Links2 project that uses 2 copies of Links2 (one for resource templates and another for a mod I am doing for a free classifieds/ads) to merge the 2 into one in the details page. I want to pass some fields (see above).. I will put >>>>> on code lines I think need to be changed for passing the strings/variables .
...Get a big cup of java for this one Smile
____________________________
The calling code starts at...
____________________________

___________site_html_templates.pl_________________
sub site_html_detailed {
# --------------------------------------------------------
# This routine will build a single page per link. It's only
# really useful if you have a long review for each link --
# or more information then can be displayed in a summary.
#
my %rec = @_;
>>>>>> return &load_template ('detailed.html', {
total => $total,
grand_total => $grand_total,
title_linked => $title_linked,
%rec,
%globals
} );
}

____________________________
Then from there goes to...
____________________________


_____________db_utils.pl_______________
sub load_template {
# --------------------------------------------------------
# Loads and parses a template. Expects to find as input a
# template file name, and a hash ref and optionally template text.
# If text is defined, then no file is loaded, but rather the template
# is taken from $text.
#

my ($tpl, $vars, $string) = @_;
(ref $vars eq 'HASH') or &cgierr ("Not a hash ref: $vars in load_template!");

if (!defined $db_template) {
require "$db_lib_path/Template.pm";
$db_template = new Template ( { ROOT => $db_template_path, CHECK => 0 } );
}
$db_template->clear_vars;
$db_template->load_template ($tpl, $string) or &cgierr ("Can't load template. Reason: $Template::error");
$db_template->load_vars ($vars) or &cgierr ("Can't load variables. Reason: $Template::error");
>>>>>> return $db_template->parse ($tpl) or &cgierr ("Can't parse template. Reason: $Template::error");
}

____________________________
and from there goes to finally Routine in...
____________________________

__________Template.pm __________________
sub parse {
# ---------------------------------------------------------------
# Parses a template.
#
my $self = shift;
my $template = shift;
>>>>>> (will add code to pickup the passed variables to be used in this routine.)

my $begin = $self->{'begin'} | | quotemeta('<%');
my $end = $self->{'end'} | | quotemeta('%>');
---- cut here for length....
____________________________
End of the way these routines originally looke before my changes/test/debugs..
==================================

NOW, for my proposed changes below... I have used print statments to do my debuging on the variables so I think I am close cause most seems to work. My Biggest problem is that the books did not who me where to put the code to start the pass in sub site_html_detailed {... so I had to guess at this..
________________________________

return &load_template ('detailed.html', {
total => $total,
grand_total => $grand_total,
title_linked => $title_linked,
%rec,
%globals
# });
},$nullx, $Category, $ID );
__________________________
Not sure if this is the right place to put the 3 strings I want to pass... $nullx, $Category, $ID. It works but I have never seen this in the books.

I cannot remember why I had to put in the $nullx variable to get things to shift right.

Also, I sure would like to know how to print out those variables above so I can better see what is being passed and where. So far I can print out 'detailed.html', $Category, and $ID. BUT, I cannot see what happens to the middle items (not that I need them. I just would feel more comfortable knowing where they went on the pass to the call.).

__________________________
sub load_template {.........
my ($tpl, $vars, $string, $string2, $string3) = @_;
__________________________

sub parse {.......
my $self = shift;
my $template = shift;
#mystuff these below variables 7-30-99 that where needed to read another sidebar file to include in detailed page
my $build_root_path = shift;
my $Category = shift;
my $ID = shift;
my $build_extension = shift;
#mystuff these above variables 7-30-99 that where needed to read another sidebar file to include in detailed page
__________________________
So far these seem to work BUT... there are so many calls to these routines from module to module I want to be sure as I can on this.

Thanks (I did not want to right a book on this Smile so I hope I did not leave out to much. To save space, I will not bother to show my code for what I finally do with the variables. (oh, what the hay... I went this far, I might as well tell you why Smile

Also, for some other info On what I have been trying to do see the following threads..

1. http://www.gossamer-threads.com/scripts/forum/resources/Forum11/HTML/000875.html

2. http://www.gossamer-threads.com/scripts/forum/resources/Forum3/HTML/002512.html

3. http://www.gossamer-threads.com/scripts/forum/resources/Forum3/HTML/002542.html

___________________________________
NOW for the WHY of it all Smile
___________________________________
I have gone this far to show what I have done so I might as well show why I have done it.. Smile
Here is part of the routine in :
Template.pm at ... sub parse {
___ cut...
# Parse includes, do this first so that the includes can include
# template tags.

my $includeFILE = "";#lets make an include directory = a subdirectory of /templates
my $ROOTdir = "";#lets make an include directory = a subdirectory of /templates

$temp =~ s#$begin\s*include\s*(.+?)\s*$end#
if (exists $self->{'inc'}{$1}) { $self->{'inc'}{$1}; }
else {

$includeFILE = $1;
$ROOTdir = ${$self}{'ROOT'};

if ($includeFILE eq "UseMyIncludes")
{
$includeFILE = "advert.htm";
$ROOTdir = "$build_root_path/$Category";
}

if (open (INC, "$ROOTdir/$includeFILE")) {
$self->{'inc'}{$1} = join ("", <INC> );
close INC;
$self->{'inc'}{$1};

}
else {
"*Open AdFile Error*<--Can't find file:<br>$ROOTdir<br>/$includeFILE-->";
}
____End of cut______________________________

Now all I do is put <%include UseMyIncludes%>
in my Resource templates as needed and the above routines will allow me to "include" my "advert.htm" files created from my second Links2 Classifieds setup. (I use the If-Include Mod from resource center in Template.pm)

Understand that both Resource/Detail (index.html) pages and Classifieds (advert.htm) are in the same category directories and merged into one final web page by using this routine.

I run 2 builds. One for Classifieds entered online for the day and the second build is for Resources/Articles validated for that day. In that order so the Classifieds (advert.htm) are sucked into the Resources/Articles during that build. Smile

Yes, I tried to figure a way to use the current <%include ?????.???%> mod but I could not. Because, it seemed to me that to acomplish this merge would require a sub/include within the include. So I ended up with this technique. Also, I wanted to try and utilize the current mods and calls already in Links2/Templates.

I would be glad to here from anyone with any other ideas that might make this work easier.

I will clean this all up a bit after I figure all this out. Later on I would even like to pass the "advert.htm" in as a variable also from links.cfg.

TimRyan



[This message has been edited by TimRyan99 (edited August 04, 1999).]
Quote Reply
Re: Help! What does this shift code do? In reply to
Ok,

I _think_ I know what you are trying to do, and why it's not working. The @ARGV and @_ are lists that pass ELEMENTS. In the &load_Template call, you are passing it the template name, then a hash (array) and then a string. That means you can pop 3 items off the ARGV list..

To verify this, check the size of @ARGV as outlined above.

To pass additional parameters to the subroutine (fortunately Perl is pretty forgivng)

Code:
my ($tpl, $vars, $string) = @_;
(ref $vars eq 'HASH') or &cgierr ("Not a hash ref: $vars in load_template!");

This is from the &load_template routine. $tpl is the template name, $vars is a hash, and is checked to be a hash. $string is a third element. Actually I haven't figured out what that does, but I'll bet some routines use it for passing another parameter.

Because of that, the _best_ way to pass variables to these routines is in the %globals array, unless you check EACH AND EVERY call to &load_template to make sure your added variables don't screw up some order.

If you do that, the best thing would probably be to create a second passed hash array, that way you could arbitrarily grow it to any size, but I'm not sure there is any advantage to that than using the %globals array.

If you pad values together to pass as $string, you need to send that to a parse routine to separate them, since they would be shifted as one parameter (again, check that by checking the value of $#ARGV in the subroutine).

Hope this helps. I'm still not awake, actually, haven't been to bed yet. Sick kids.



Quote Reply
Re: Help! What does this shift code do? In reply to
I would be interested in seeing what your project looks like once completed.
Quote Reply
Re: Help! What does this shift code do? In reply to
I think I've been at this too long today. I need to look at this and see what you are trying to do. I didn't catch it on the first run through.
Quote Reply
Re: Help! What does this shift code do? In reply to
hehe Smile Me either, and I wrote it.. Smile Sorry, it was 4am on the latter explaination and I did not want to take up to much disk space Smile

I am currently doing R&D on this via my office computer with Win/98(sucks) and apache(great). I have been waiting to get this along fairly well before I upload it to my Linux/apache server.

Perhaps, I might take some time and mod this soon for online. I just hate putting up something half/hazard Smile

I have many other search engines I have modified over the past 3 years and I have been waiting for just the right cgi scripts to come along so that I would not have to write from scratch. Links2 with its templates and HTML generation was just the right mix of what I needed to complete this long awaiting project.

My next step (after this Resource and Classifieds project is done) will be to upgrade some of my other projects with templates and HTML. What I really want to do is make the HTML generator secondary and add an instant-access-of-Links.db. Sort of like a links2 with templates and DBMan combined.

Thanks all. (especially Alex Smile
TimRyan



[This message has been edited by timryan (edited August 05, 1999).]
Quote Reply
Re: Help! What does this shift code do? In reply to
Thanks pugdog. You have given me lots to go over above. Though I am a 25 year vet in basic, I have only been learning perl for the past 2 years (on and off). I have found links2 a very great learning tool. So, I will have to digest what you have here.

Even though the code I gave above is actually working for me at this point I am not confident in my Perl knowledge to leave it at that.

I like the %global idea for passing. I am not sure how to pick the %global up in the Template.pm - sub parse routine though. I use print statements for my debugging. So, how might I go about seeing what is in %global?

I am able to print out the shifted variables (for what that is worth).

My shifts are picking up each variable without a parse routine (see above..sub load_template) and be sure to see how I pass them (just below the %global in site_html_templates.pl - return &load_template ('detailed.html', {
.... (see above).

Keep in mind that I am a "trial & error" learner. When I cannot find it in the book I try it and if it work I use it. If not well, onward. Smile But since Perl is so forgiving this can be a bad way to program Smile


Thanks
TimRYan
PS. hope the kids are better. Mine are off on their own now since last year so got lots of time to play now Smile

UPDATE1:
I hit the books and I used
print ();#prints @ARGV
in each routine above and I see the links.db record is in all, including where I need it in Template.pm sub parse.

Now all I need is to figure out how to grab all that there in that routine. Not sure how to do this. Also I want to be sure not to mess up the shifts there.


[This message has been edited by timryan (edited August 05, 1999).]
Quote Reply
Re: Help! What does this shift code do? In reply to
And now, the official explanation as per perldoc:

Code:
shift ARRAY
shift Shifts the first value of the array off and returns it,
shortening the array by 1 and moving everything down. If
there are no elements in the array, returns the
undefined value. If ARRAY is omitted, shifts the `@_'
array within the lexical scope of subroutines and
formats, and the `@ARGV' array at file scopes or within
the lexical scopes established by the `eval ''', `BEGIN
{}', `END {}', and `INIT {}' constructs. See also
`unshift()', `push()', and `pop()'. `Shift()' and
`unshift()' do the same thing to the left end of an
array that `pop()' and `push()' do to the right end.

That why I prefer English, although English can be confusing too! Smile



[This message has been edited by Bobsie (edited August 05, 1999).]
Quote Reply
Re: Help! What does this shift code do? In reply to
Thanks bobsie. That confirms a lot for me on my debug prints. I am sure I will have to come back and read that paragraph many... many more times as I experiment.

Now..., (back to the Template sub parse routine)...

1. if someone could tell me how to grab that data I get with the debug print (). That would be nice.

2. And more importantly for us all, I cannot figure out how to pick up the %global. That seems to be getting passed from
____________________________
___________site_html_templates.pl_________________
sub site_html_detailed {
my %rec = @_;
return &load_template ('detailed.html', {
total => $total,
grand_total => $grand_total,
title_linked => $title_linked,
%rec,
%globals
},$nullx, $Category, $ID );
}
____________________________

If you look at my shifts above I can pickup the $Category and $ID I pass above but, why not (someway) get them from the %rec and %globals???@! How?

I have been hitting the books I have on perl on how to pass variables and receive variables in calls/routines and notice there seems to be, not only many ways, but many effects each "way" has on arrays and strings. But, everything on this subject in the books is scattered all over the place and makes hard for reading.

I would love to have someone rip the latter example here appart and explain how each of the above variables passed and what the diferences are in each. (array, string, %, $, associative, etc). This would be good for others doing mods also.

Again, thanks all so far on what you have shared above. It is helping put the puzzle together. Smile Someday we might start up a doc project for links2 like they have for linux.

"Information is the life-blood of the web and Links2 is its heart Smile"

Thanks,
TimRyan

PS. My background is from old basic programming and I love perls high level Smile



[This message has been edited by timryan (edited August 06, 1999).]

[This message has been edited by timryan (edited August 06, 1999).]
Quote Reply
Re: Help! What does this shift code do? In reply to
FWIW -- perl seems to have problems passing more than one hash or array to a subroutine, which is why more complex routines pass an explict reference to the hash or array.

Check a text or the manual on references, but you can pass \@array or \%hash and perl won't flatten them, and shift will pop the values properly. You have to handle them properly in your subroutine, since those are now scaler references to the array or hash, not the hash or array themselves.

This is getting into the stuff that drives people crazy, which is why its just easier to add a few references to the %globals hash, which is passed to all the templates.



[This message has been edited by pugdog (edited August 06, 1999).]
Quote Reply
Re: Help! What does this shift code do? In reply to
pugdog ... you said
Quote
______________________
This is getting into the stuff that drives people crazy, which is why its just easier to add a few references to the %globals hash, which is passed to all the templates.
_______________________

Any ideas on how to do this?

I agree with what you say and I have been trying to come up with some code to do that. I do not think I like using the shifts because I think it might be effecting the way the other modules use the same routine.

I have been looking through the modules to see some examples but cannot find anything yet.

Anyone?
Thanks
TimRyan
Quote Reply
Re: Help! What does this shift code do? In reply to
In the %globals hash at the top of site_html_templates...

just insert whatever variables you want to use, and get passed:

nullx =>$nullx,
Category_x => $Category_x,
ID_x => $ID_x,


These are declaired inside the site_html_templates.pl file, so are global to that file, and to any subroutine called by this file to which they are passed.

I've kind of lost the original intent of all this Smile
Quote Reply
Re: Help! What does this shift code do? In reply to
Thanks pugdog.
Correct me if I am wrong here, but I believe the latter ...
____________________________________________
Category_x => $Category_x,
____________________________________________

...is for allowing us to use say
____________________________________________
<%Category_x%>
____________________________________________

in a template file to catch/display the $Category_x variable content. Is this my correct learning here?

Where as, I need to do just the opposite. I need to pass a variable from a template to a program/mod (sort-of).

Now, to re-hash (no pun intended Smile; what I have been spending the past full time week on ... Frown :

Thanks to your help on making this topic mature into the next step I have decided to post this onto another thread at:

http://www.gossamer-threads.com/scripts/forum/resources/Forum3/HTML/002664.html

So we are not off the original subject line of this thread Smile

Thanks
TimRyan


[This message has been edited by timryan (edited August 07, 1999).]