Gossamer Forum
Home : Products : Gossamer Links : Discussions :

form_link self->code problem

Quote Reply
form_link self->code problem
Hi there,

I'm trying to do a pre_hook into form_link and form_display like this:


[
'form_link',
'PRE',
'Plugins::Custom::custom_form_link',
'1'
],

Then in Custom.pm I have this code:

sub custom_form_link {
# -------------------------------------------------------------------
# This subroutine will get called whenever the hook 'form_link'
# is run. You should call GT::Plugins->action ( STOP ) if you don't
# want the regular code to run, otherwise the code will continue as
# normal.
#
my ($self, $opts) = @_;
$self->{code}->{Business_Hours} = \&form_hours;
return ($self,$opts);
}


The problem is that when the rest of GT's code gets run, I lose all Expiry_Form code and the Username code that GT created.

I looked in Links::HTML::Links.pm and found the following in _plg_form :

sub _plg_form {
# -------------------------------------------------------------------
# Displays a form.
#
my ($self, $opts) = @_;

$self->{code}->{ExpiryDate} = \&form_expiry;

GT's $self->{code} contains the form_expiry
but $opts->{code} contains my disp_hours (shouldn't this be in $self?)

The real problem is that the resulting form displays my custom_form element, but not GT's

so it seems that I'm not passing back the information from my plugin properly OR $self is not passed through to my plugin, but I can't figure out what I'm doing wrong, or maybe this kind of plugging in isn't possible?

Any ideas?

peace.

klangan
Quote Reply
Re: [klangan] form_link self->code problem In reply to
Hi,

Did you get anywhere with this? I'm trying to do something similar.
Quote Reply
Re: [afinlr] form_link self->code bug In reply to
No I haven't,

It seems that gt looks either to self or opts instead of checking opts then self for the custom coding. The only way to keep GT's code in tact is to copy it into your plugin, but you'll need to do it for each one of their custom codes that currently exist and you'll need to keep on top of any new ones that they develop. So yeah, plugging into this section isn't really much of an option cause it means losing functionality. Hope this can be fixed so it works as we expect.

peace.
Quote Reply
Re: [klangan] form_link self->code bug In reply to
OK - thanks for replying.

I have even tried copying all the code into my plugin and I still can't get it to work Unsure

Any pointers from someone at GT?
Quote Reply
Re: [klangan] form_link self->code bug In reply to
It's taken a long time - but I finally managed to get my plugin to work! (This was out of necessity - I had two Links implementations running on the same mod_perl server so having edits for one in the core code became a big problem).

Unfortunately it involved editing the core files to pass $self into the plugin. I'm hoping that GT will make the changes so that this edit is no longer necessary.

Laura.
The UK High Street
Quote Reply
Re: [afinlr] form_link self->code bug In reply to
Hi afinlr,

I'd forgotten about this conversation. I found a way around it by doing this inside of my code.


$self->{code}->{myfield} = \&mycode;
$self->{code}->{ExpiryDate} = \&Links::HTML::Links::form_expiry;

I generally don't use mod_perl so I have no idea how that will affect it. But I haven't had any problems with calling the file and subroutine explicitly with \&Links::HTML::Links::form_expiry;

hope that helps.

peace.
Quote Reply
Re: [klangan] form_link self->code bug In reply to
That looks easy - but I haven't understood how you are using it. Is this a change that you have made inside the core code or inside a plugin?
Quote Reply
Re: [afinlr] form_link self->code bug In reply to
I put it inside my plugin:
I plug into display_link and form_link.

look in Links::HTML::Links::_plg_display and _plg_form.

You'll see the GT code and how they call \&form_expiry; or \&disp_expiry;
the problem is that we lose those self->{code}->{ExpiryDate} when plugging in.
So in order to re-establish them and NOT have to copy the code, we need to create the self->{code}->{ExpiryDate} code with an explicit call to that subroutine as I mentioned above.

If you're pluggin into display_link, you'll need to do the same with LinkOwner.


hope that helps.

sub form_link {
# -------------------------------------------------------------------
# This subroutine will get called whenever the hook 'form_link'
# is run. You should call GT::Plugins->action ( STOP ) if you don't
# want the regular code to run, otherwise the code will continue as
# normal.
#
my ($self, $opts) = @_;
$self->{code}->{myfield} = \&form_myfield;
$self->{code}->{ExpiryDate} = \&Links::HTML::Links::form_expiry;

}
Quote Reply
Re: [klangan] form_link self->code bug In reply to
Hmm - I did that already in my plugin. But I couldn't get my plugin to work without pushing $self into the plugin by editing the core code. I don't understand how you had the $self variable available. Maybe I've just missed some code at the top of the plugin. I've tried dumping all the variables that are read in to see what is there and this was the only way I could see to do it - but I haven't had much sleep!
Quote Reply
Re: [afinlr] form_link self->code bug In reply to
As you have already noticed, the code in the original post is wrong in that the plugin hook only receives one argument (the opts hash ref). Because of that, the code is actually modifying $opts and not $self. Later on in the code, $opts's values actually replace anything set in $self, so that's why all the default code overrides stop working. As for your change, unfortunately, doing so would break any existing plugins (if there are any). Instead, I have fixed the core code to change $opts instead of $self. Here's a patch:
Code:
retrieving revision 1.22
retrieving revision 1.23
diff -u -b -r1.22 -r1.23
--- Links.pm 29 Oct 2006 10:49:58 -0000 1.22
+++ Links.pm 22 Mar 2007 22:03:08 -0000 1.23
@@ -3,7 +3,7 @@
#
# Website : http://gossamer-threads.com/
# Support : http://gossamer-threads.com/scripts/support/
-# Revision : $Id: Links.pm,v 1.22 2006/10/29 10:49:58 brewt Exp $
+# Revision : $Id: Links.pm,v 1.23 2007/03/22 22:03:08 brewt Exp $
#
# Copyright (c) 2001 Gossamer Threads Inc. All Rights Reserved.
# Redistribution in part or in whole strictly prohibited. Please
@@ -51,9 +51,13 @@
# Displays a record.
#
my ($self, $opts) = @_;
- $self->{code}->{LinkOwner} = \&disp_username;
- $self->{code}->{ExpiryDate} = \&disp_expiry;
- $self->{code}->{ExpiryCounted} = $self->{code}->{ExpiryNotify} = $self->{code}->{LinkExpired} = sub { '' };
+ $opts->{code}->{LinkOwner} ||= \&disp_username;
+ $opts->{code}->{ExpiryDate} ||= \&disp_expiry;
+
+ my $hidden = sub { '' };
+ $opts->{code}->{ExpiryCounted} ||= $hidden;
+ $opts->{code}->{ExpiryNotify} ||= $hidden;
+ $opts->{code}->{LinkExpired} ||= $hidden;

my $out = $self->SUPER::display($opts);
if ($opts->{mode} =~ /$SHOW_CAT_LIST/o) {
@@ -82,16 +86,13 @@

my $link_id = $opts->{values}->{ID} || $self->{input}->{ID};

-# Remove any previous code ref.
- delete $self->{code}->{LinkOwner};
-
# Hide fields we don't want to show on add/modify forms.
if ($opts->{mode} and $opts->{mode} =~ /$FORM_HIDE/o) {
$opts->{hide} ||= [];
push @{$opts->{hide}}, @{$FORM_HIDE_FIELDS};
}

- $self->{code}->{ExpiryDate} = \&form_expiry;
+ $opts->{code}->{ExpiryDate} ||= \&form_expiry;

# Add javascript to display the original values for text/textarea columns
if ($opts->{show_diff} and $link_id) {
@@ -126,8 +127,8 @@
next COL if $_ eq $col;
}

- if ((not defined $opts->{values}->{$col} or $current->{$col} ne $opts->{values}->{$col}) and !exists $self->{code}->{$col}) {
- $self->{code}->{$col} = $textarea;
+ if ((not defined $opts->{values}->{$col} or $current->{$col} ne $opts->{values}->{$col}) and not $opts->{code}->{$col}) {
+ $opts->{code}->{$col} = $textarea;
}
}
}

It won't patch cleanly against 3.2 since there have been a few other changes in the file since then, but the idea is there.

Adrian
Quote Reply
Re: [brewt] form_link self->code bug In reply to
Frown I'm giving up. I've spent hours on this, but having got it to work as a plugin with the extra variable fed in I still can't get my other installation to work - I think I'm going to have to put them on separate mod_perl servers. If you want to run several installations under mod_perl do they all have to have the same Plugins? Is it only the database that can be different?

Since I'm going to have to make changes to the core code anyway to get this plugin to work (I can't see how it can work just by using $opts), I think I'll leave everything as it was in the core code. I am disappointed. Whenever I want to make big modifications to Links and try to make use of the plugin system it seems that there is always something missing that stops it from working. Keeping track of changed core files is really difficult so upgrading the software becomes a huge chore.
Quote Reply
Re: [afinlr] form_link self->code bug In reply to
With the above patch, it works (I'm working on a project right now which also does this). The plugin code is essentially the same:
Code:
sub form_link {
my $opts = shift;

$opts->{code}->{MyColumnName} = sub {
...
};
return $opts;

Adrian
Quote Reply
Re: [brewt] form_link self->code bug In reply to
I'm feeling defeated right now so I think I'll get some sleep and have another go at this tomorrow.

Thanks for the replies.
Quote Reply
Re: [brewt] form_link self->code bug In reply to
The problem that I have is that I need to run my code instead of form_link, display_link, etc. This doesn't seem to be possible.

I have another set of tables like CatLinks, Category and I want to show the select box for this under the category select box. I have written all the code for this and it works as a modification to the core code. I have it all working as a Plugin but only with the $self variable. I can't see how to overwrite the code without this variable.

It just needs to be added onto the output so I could use a post hook if I had the $opts variable available in the post hook - but it isn't.

I can't see how to proceed with this now. Any pointers would be appreciated.

Thanks,
Laura.
The UK High Street
Quote Reply
Re: [afinlr] form_link self->code bug In reply to
Well - I'm almost there I think. I'm overwriting the code in the plugin again as I can't see another way to do what I need. I'm just stuck on displaying the form - I'm not too hot on object oriented programming so I'm not sure how I should rewrite

my $out = $self->SUPER::form($opts);

so it isn't using the $self variable.

Edit: I found it in this post http://www.gossamer-threads.com/...i?post=198412#198412 - thanks klangan.

my $db= $DB->table('Links');
my $html = new GT::SQL::Display::HTML::Table({db=>$db});
my $out = $html->form($opts);

Last edited by:

afinlr: Mar 24, 2007, 6:43 PM
Quote Reply
Re: [afinlr] form_link self->code bug In reply to
Not quite there yet. I can't get the modify form to work. I have a pre hook on modify_link that is overwriting the code from Links::Table::Links.pm

I'm stuck on this line:
my $ret = $self->SUPER::modify($set);

I've tried
my $db=$DB->table('Links');
my $ret=$db->modify($set);

Edit: This is also a problem with $db->add. It seems to be calling the plugin in a loop which is why it is hanging.

Last edited by:

afinlr: Mar 24, 2007, 8:53 PM
Quote Reply
Re: [afinlr] form_link self->code bug In reply to
Smile I've discovered Ivan's Claim Link plugin - ignore all previous posts as I'm sure that by analysing this I can work out how to do everything I need.