Gossamer Forum
Quote Reply
Cache Page question
Is there a way to include the data in the "Page" table in a search? The idea is to include the data in the search results and truncate the 50 characters before the search term and the 50 characters after the search term. For example, if I searched for "Dog", the results would show up like:

- Raising a puppy
http://www.puppyinfo.com
"... and a good home. As the puppy grows into a dog you may need more..."

or something like that??

</not a clue>
Quote Reply
Re: [Dinky] Cache Page question In reply to
Hi Dinky,

It's possible. But to make it near perfect, you have to modify search.pm, because of this, I have not included this feature into the plugin otherwise it is not a plugin but a mod.

The problem is if the plugin is hooked to post search result, that result returned by search.pm is html formatted (I hope future version will change this, not doing formatting in code but using template). If you want to search the cached_page table and combine these two, first the plugin has to know what result from links table have been returned that means it needs varibles not html formatted records (you can parse it back into varibles, but it costs time). Also this problem hinders result combination and resorting. To work around, I have to modify search.pm.

To see a demo, please try the site I sent you before.

There are some extra work to be done before the cache_page table can be searched. This is to make linksql index the table, then when pages are added to the table, they will get automatically indexed.

If you don't care modifying your search.pm, I can post the procedures and code needed to make the table searchable.

Long

Last edited by:

long327: Apr 29, 2004, 10:25 AM
Quote Reply
Re: [long327] Cache Page question In reply to
If you could post the code, that would be appreciated.

As I have CachePage....
Quote Reply
Re: [webslicer] Cache Page question In reply to
Long,
Thanks, if you post the code, I will give it a try, any suggestions on truncating the search...

</not a clue>
Quote Reply
Re: [Dinky] Cache Page question In reply to
In Reply To:
any suggestions on truncating the search...

What do you mean by truncating the search?

Long
Quote Reply
Re: [long327] Cache Page question In reply to
As per the example on the start of the thread, once you conduct a search for example "Dog", instead of just listing the link and URL/Description, it will find on the cache page where the search term appears, and print out the 50 or so characters before and after the search term....

</not a clue>
Quote Reply
Re: [Dinky] Cache Page question In reply to
Here are steps to make cache pages searchable

Step one.
To make linksql index Cached_Page table:

1. Login to your linksql admin, then paste this url into your browse

http://yourdoman/your_linksql_script_dir/admin/admin.cgi?db=Cached_Page&do=editor_table_form
(thanks to afinlr for the secret)
Please note if you have used a different name for the cached page table, you have to change the "Cached_Page" in the URL to your table name.

2. In the Indexing Scheme dropdown list, choose INTERNAL, then click "Update table", by doing this, linksql will add two tables to your database: Cached_Page_Score_List and Cached_Page_Word_List.

3. Add this code to nph_index.cgi at (about) line 176 before this line "# All done." (Make backup before doing this)
Code:
print "Reindexing Cached Page Database ... ";
my $cached = $DB->table('Cached_Page');
$total = $cached->count || 0;
$weights = $cached->weight || {};
$found = 0;
foreach (keys %$weights) {
$weights->{$_} > 0 and ($found = 1);
}
if (! $found) {
if ($use_html) {
print "<font color=red><b>No search weights have been defined, skipping!</b></font>\n\n";
}
else {
print "No search weights have been defined, skipping!\n\n";
}
}
else {
print "$total cached pages.\n";
$cached->reindex( { tick => 1000, max => 10000 } );
print "\nDone!\n\n";
}

4. Do the initial indexing.
You can do it by clicking repair search in your browser or in shell by typing perl nph-index.cgi.

If you have already stored many cached pages, this process may take long and the Cached_Page_Score_List and Cached_Page_Word_List tables may get big.

After initial indexing, you don't need to do it again. Every time you cache a new page, it will get automatically indexed. You will see the records growing in Cached_Page_Score_List and Cached_Page_Word_List table after a page is cached, if not, the automatic indexing is not working!

Step two. Modify Admin/Links/User/Search.pm (Make backup before doing this)

Below is the modified the version of search.pm. Code in red is added, in blue is commented out

Search.pm
Code:
# ==================================================================
# Links SQL - enhanced directory management system
#
# Website : http://gossamer-threads.com/
# Support : http://gossamer-threads.com/scripts/support/
# CVS Info : 087,069,082,087,085
# Revision : $Id: Search.pm,v 1.14 2002/05/13 16:59:50 alex Exp $
#
# Copyright (c) 2001 Gossamer Threads Inc. All Rights Reserved.
# Redistribution in part or in whole strictly prohibited. Please
# see LICENSE file for full details.
# ==================================================================package Links::User::Search;
# ==================================================================
use strict;
use Links qw/$DB $IN $USER $CFG/;
use Links::SiteHTML;
use Links::Build;sub handle {
#--------------------------------------------------------------------------------
# Determine whether we are displaying the search form, or doing a
# search.
#
my $db = $Links::DB->table('Links');
my $results = {};
my $args = $IN->get_hash;# Remove search fields we aren't allowed to search on.
if ($CFG->{search_blocked}) {
foreach my $col (@{$CFG->{search_blocked}}) {
$col =~ s/^\s*|\s*$//g;
if ($args->{$col}) {
delete $args->{$col};
$IN->delete ($col);
}
delete $args->{"$col-lt"};
$IN->delete ("$col-lt");
delete $args->{"$col-gt"};
$IN->delete ("$col-gt");
}
}
# Make sure we only search on validated links.
$IN->param('isValidated', ['Yes']);# If query is set we know we are searching.
defined $args->{'query'} and ($args->{query} =~ /\S/) and return search();

# Otherwise, if we pass in a field name, we can search on that too.
foreach (keys %{$db->cols}) {
if ((defined $args->{$_} and length $args->{$_}) or
(defined $args->{"$_-lt"} and length $args->{"$_-lt"}) or
(defined $args->{"$_-gt"} and length $args->{"$_-gt"}))
{
return search();
}
}
print $IN->header();
print Links::SiteHTML::display('search');
}sub search {
# ------------------------------------------------------------------
# Do the search and print out the results.
#
my $results = GT::Plugins->dispatch ($CFG->{admin_root_path} . '/Plugins', 'search_results', \&query, {});
if (defined $results->{error}) {
print $IN->header();
print Links::SiteHTML::display ('search', $results);
}
else {
print $IN->header();
print Links::SiteHTML::display ('search_results', $results);
}
if ($CFG->{debug_level} > 1) {
print "<blockquote><pre>", GT::SQL->query_stack_disp , "</pre></blockquote>";
}
}sub query {
# ------------------------------------------------------------------
# Query the database.
#
my $query = $IN->param('query');
my $term = $IN->escape($IN->param('query'));# First get our search options.
my $args = $IN->get_hash;
$args->{query} =~ s,^\s*|\s*$,,g;
$args->{bool} = (defined $args->{bool} and $args->{bool} =~ /^(and|or)$/i) ? uc $1 : $CFG->{search_bool};
$args->{nh} = (defined $args->{nh} and $args->{nh} =~ /^(\d+)$/) ? $1 : 1;
$args->{mh} = (defined $args->{mh} and $args->{mh} =~ /^(10|25|50|100)$/) ? $1 : $CFG->{search_maxhits};
$args->{substring} = defined $args->{substring} ? $args->{substring} : $CFG->{search_substring};
$args->{so} = (defined $args->{so} and $args->{so} =~ /^(asc|desc)$/i ? $1 : '');
$args->{sb} and ($args->{sb} =~ /^[\w\s,]+$/ or ($args->{sb} = ''));
#Cached_Page add two lines
my $whole_word = 1 if $args->{substring}=0; #For making summary
my @search_words = split('\s+',$args->{query});

# Get our Links/Category db object.
my $links = $Links::DB->table('Links');
my $categories = $Links::DB->table('Category');# We don't do a category search if we only have a filters.
my $filter = 0;
if (! defined $query or ($query eq '')) {
$filter = 1;
}
$args->{filter} = $filter;# Then do the search.
$args->{callback} = \&_cat_search_subcat if ($args->{catid});
my $orig_sb = $args->{sb};
my $orig_so = $args->{so};
$args->{sb} = $CFG->{build_sort_order_search_cat};
$args->{so} = '';
$filter and $args->{sb} =~ s/score//;
my $cat_sth = $categories->query_sth ($args) unless ($filter);
my $cat_count = $filter ? 0 : $categories->hits(); $args->{callback} = \&_search_subcat if ($args->{catid});
$args->{sb} = $orig_sb ? $orig_sb : $CFG->{build_sort_order_search} || '';
$args->{so} = (defined $orig_so and $orig_so =~ /^(asc|desc)$/i) ? $1 : 'ASC';
$filter and $args->{sb} =~ s/score//;
my $link_sth = $links->query_sth ($args);
my $link_count = $links->hits;
#Cached_Page add
# query cached table
$args->{field_name}='Page';
$args->{bool} = (defined $args->{bool} and $args->{bool} =~ /^(and|or)$/i) ? uc $1 : $CFG->{search_bool};
$args->{substring} = defined $args->{substring} ? $args->{substring} : $CFG->{search_substring};
my $cache_db = $DB->table ('Cached_Page'); #Change the table name if you have used a different one.
my $cache_sth = $cache_db->query_sth($args);
my $cache_count = $cache_db->hits;
# Cached_Page end
# Return if no results.
unless ($link_count or $cat_count or $cache_count) { #add $cache_count to this line
return { error => Links::language('SEARCH_NOLINKS'), term => $term };
}
#Cached_Page add
# First combine all links matches
my $results;
my (@link_ids, $seen); # id hit from links table
if ($link_count) {
$results = $link_sth->fetchall_hashref;
@link_ids = map { $_->{ID} } @$results;
for my $id (@link_ids) {
$seen->{$id} ++;
}
}

# Now get cache page
if ($cache_count){
my (@cache_ids, $result_fm_cache);
while (my $cache_hit = $cache_sth->fetchrow_hashref) {
# make summary from page content for display
my $page = _make_summary(\@search_words, $cache_hit->{Page}, $whole_word);
push @cache_ids, $cache_hit->{LinkID} unless exists $seen->{$cache_hit->{LinkID}}; # get ids only from cached table
$result_fm_cache->{$cache_hit->{LinkID}} = $page;
}
# Now need to query links table again to get basic link variable for those extra hits from cached table
# I know this will slow down search speed, any better algo here?
if (@cache_ids >=1){
my $cond = GT::SQL::Condition->new('ID', 'IN', \@cache_ids);
my $extra_links = $links->select ( {isValidated => 'Yes'}, $cond);
my $extra_count = $links->hits;
$link_count = $link_count + $extra_count; # add to sum
my $newlinks;
## There must be results, so no need to test $extra_count
while (my $newlink = $extra_links->fetchrow_hashref) {
# Replace description with cached page summary for display so users will see the matches
$newlink->{Description}= $result_fm_cache->{$newlink->{ID}};
push @{$results}, $newlink; # add extra links to the pool
}
}
}
#Cached_Page end
# Now format the category results.
my $count = 0;
my ($category_results, @category_results_loop);
if (!$filter and $cat_count) {
while (my $cat = $cat_sth->fetchrow_hashref) {
last if ($count++ > $args->{mh});
my $title = Links::Build::build ('title_linked', { name => $cat->{Full_Name}, complete => 1, home => 0 });
$category_results .= "<li>$title\n";
$cat->{title_linked} = $title;
push @category_results_loop, $cat;
}
}# And format the link results.
my ($link_results, %link_output);
if ($link_count) {
#Cached_Page remove one line here
#my $results = $link_sth->fetchall_hashref;
$links->add_reviews ($results);
if ($CFG->{build_search_gb}) {
#Cached_Page remove one line
#my @ids = map { $_->{ID} } @$results;
my $catlink = $DB->table('CatLinks','Category');
#Cached_Page remove one line
#my %names = $catlink->select ('LinkID', 'Full_Name', { LinkID => \@ids })->fetchall_list;
#Cached_Page add one line
my %names = $catlink->select ('LinkID', 'Full_Name', { LinkID => \@link_ids })->fetchall_list;
foreach my $link (@$results) {
push @{$link_output{$names{$link->{ID}}}}, $link;
}
}
else {
push @{$link_output{none}}, @$results;
}
}# Join the link results by category if we are grouping.
my @link_results_loop;
if ($CFG->{build_search_gb}) {
foreach my $cat (sort keys %link_output) {
my $title = Links::Build::build ('title_linked', { name => $cat, complete => 1, home => 0 });
$link_results .= "<p><b>$title</b>" . join ("", map { Links::SiteHTML::display('link', $_) } @{$link_output{$cat}});
$link_output{$cat}->[0]->{title_linked} = $title;
push @link_results_loop, @{$link_output{$cat}};
}
}
else {
$link_results = join ("", map { Links::SiteHTML::display('link', $_) } @{$link_output{none}});
push @link_results_loop, @{$link_output{none}};
}# Generate a toolbar if requested.
my $toolbar;
if (($link_count > $args->{mh}) or ($cat_count > $args->{mh})) {
my $url = $IN->url ( { query_string => 1 } );
$url =~ s/([;&?]?)nh=(\d+)/($1 and $1 eq '?') ? '?' : ''/eg;
$toolbar = Links::Build::build ('search_toolbar', {
url => $url,
numlinks => $link_count > $cat_count ? $link_count : $cat_count,
nh => $args->{nh},
mh => $args->{mh}
});
}
else {
$toolbar = '';
}# If we are bolding the results, let's bold them.
if ($CFG->{search_bold}) {
my $tempquery = $args->{query};
$tempquery =~ s/[+\-"']//g;
my @terms = split /\s/, $tempquery;
foreach my $term (@terms) {
next unless ($term);
$term =~ s/^\s*|\s*$//;
if ($term =~ s/(.+)\*(.*)/$1/) {
push @terms, $2 if ($2);
$term = $1;
}
$link_results =~ s,(<[^>]+>)|(\Q$term\E),defined($1) ? $1 : "<B>$2</B>",gie if ($link_results);
$category_results =~ s,(<[^>]+>)|(\Q$term\E),defined($1) ? $1 : "<B>$2</B>",gie if ($category_results);
}
} # Print the output.
my $results = {
link_results => $link_results,
link_results_loop => \@link_results_loop,
category_results => $category_results,
category_results_loop => \@category_results_loop,
link_hits => $link_count,
cat_hits => $cat_count,
next => $toolbar,
term => $term
};
return $results;
}sub _search_subcat {
# -------------------------------------------------------------------
# First argument is the query/table object, second argument is the current
# result set (note: can be quite large). Must return a new result set.
#
my ($query, $results) = @_;
return $results unless (keys %$results); # No matches. my $cat_db = $DB->table ('Category');
my $catlink_db = $DB->table ('CatLinks', 'Category');# We need the full name of the category.
my @cat_ids = $IN->param('catid') or return $results;
my (@children, %seen);
foreach my $id (@cat_ids) {
next if ($id !~ /^\d+$/);
my $child = $cat_db->children($id) or next;
push @children, @$child, $id;
}
@children or return $results;
@children = grep { ! $seen{$_}++ } @children;# Now do the joined query.
my $link_ids = '(' . join(',', keys %{$results}) . ')';
my $cat_ids = '(' . join(',', @children) . ')';
my $cond = GT::SQL::Condition->new (
'CategoryID', 'IN', \$cat_ids,
'LinkID', 'IN', \$link_ids
);
my $sth = $catlink_db->select ($cond, ['LinkID']);
my $filtered = {};
while (my ($id) = $sth->fetchrow_array) {
$filtered->{$id} = $results->{$id};
}
return $filtered;
}sub _search_subcat_and {
# -------------------------------------------------------------------
# Search subcategories using AND.
#
my ($query, $results) = @_;
return $results unless (keys %$results); # No matches my $cat_db = $DB->table ('Category');
my $catlink_db = $DB->table ('CatLinks', 'Category');# We need the full name of the category.
my @cat_ids = $IN->param('catid') or return $results;
my %final = %$results;
foreach my $id (@cat_ids) {
next unless ($id =~ /^\d+$/);
my @children;
my $childs = $cat_db->children($id);
push @children, @$childs, $id;
my $cond = GT::SQL::Condition->new(
CategoryID => 'IN' => \@children,
LinkID => 'IN' => [ keys %final]
);
%final = ();
my $sth = $catlink_db->select($cond, ['LinkID']);
while (my $link_id = $sth->fetchrow_array) {
$final{$link_id} = $results->{$link_id};
}
}
return \%final;
}sub _cat_search_subcat {
# -------------------------------------------------------------------
# First argument is the query/table object, second argument is the current
# result set (note: can be quite large). Must return a new result set.
#
my ($query, $results) = @_;
return $results unless (keys %$results); # No matches. my $cat_db = $DB->table('Category');
my @cat_ids = $IN->param('catid') or return $results;
my (@children, %seen);
foreach my $id (@cat_ids) {
next if ($id !~ /^\d+$/);
my $child = $cat_db->children($id) or next;
push @children, @$child, $id;
}
@children or return $results;
@children = grep { ! $seen{$_}++ } @children; my %subcats = map { $_ => 1 } @children;
my $filtered = {};
while (my ($k, $s) = each %$results) {
$filtered->{$k} = $s if (exists $subcats{$k});
}
return $filtered;
}sub _make_summary {
#--------------------------------------------------------------------
#Make a excerpt from matched sentences of cached pages
# Modified from KSearch v1.4, Copyright (C) 2000 David Kim (kscripts.com)
my ($terms, $page, $whole_word) = @_;
my ($desc, $line, $pre, $post, $match, $prem, $postm, $bdy);
my $SHOW_MATCHES_LENGTH=150; #excerpt sentence length for result
my $show_matches = 1; # how many matches to show
my @lines;
$whole_word =1;
my $spaces = " " x $SHOW_MATCHES_LENGTH;
$bdy = $page;
$bdy =~ s/&lt;.*?&gt;|&amp;\w+;|&\w+;|&#\d+;/ /gi;
foreach my $term (@$terms) {
my $count;
if ($whole_word==1) {
while ($count < $show_matches && $bdy =~ /\b$term\b/gis) {
$count++; $pre = "$`"; $post = "$'"; $match = $&;
my $LENGTH = int (($SHOW_MATCHES_LENGTH - length $match)/2);
$pre =~ m/\b(.{0,$LENGTH})$/; $prem = $1;
$post =~ m/^(.{0,$LENGTH})\b/; $postm = $1; $post = "$'", $bdy = "$pre $post";
$line = join("", '...', $prem, $match, $postm, '...');
push @lines, $line;
}
} else {
while ($count < $show_matches && $bdy =~ /$term/gis) {
$count++; $pre = "$`"; $post = "$'"; $match = $&;
my $LENGTH = int (($SHOW_MATCHES_LENGTH - length $match)/2);
$pre =~ m/\b(.{0,$LENGTH})$/; $prem = $1;
$post =~ m/^(.{0,$LENGTH})\b/; $postm = $1; $post = "$'", $bdy = "$pre $post";
$line = join("", '...', $prem, $match, $postm, ' ');
push @lines, $line;
}
}
}
return join(" ", @lines);
}
1;


After modifying Search.pm, give it a try by searching something in user's interface.

I have attached the modified Search.pm in case you cannot keep the format by copying the code from here.

I hope it works for you guys.

Long

Last edited by:

long327: Apr 29, 2004, 11:11 PM
Quote Reply
Re: [Dinky] Cache Page question In reply to
Quote:
As per the example on the start of the thread, once you conduct a search for example "Dog", instead of just listing the link and URL/Description, it will find on the cache page where the search term appears, and print out the 50 or so characters before and after the search term....

I see. I call it excerpt or summary. It certainly does.

Long
Quote Reply
Re: [long327] Cache Page question In reply to
Last thing, it works okay, but the Cached_Page table does not have a place to change the search weight, How do I set it up so I can change it. Currently when I run nph-index.cgi i get:

Reindexing Cached Page Database ... No search weights have been defined, skipping!

All Done (22.82 s)


Thanks,

</not a clue>
Quote Reply
Re: [Dinky] Cache Page question In reply to
I am sorry I missed one thing.

When you have load the table property modification form by using the url
http://yourdoman/your_linksql_script_dir/admin/admin.cgi?db=Cached_Page&do=editor_table_form

Besides change the index method, you have also to click on the "Page" column (the 3rd position) and give it a search weight such as "2".

After this change, everything should work fine.

Long

Last edited by:

long327: Apr 30, 2004, 12:47 AM
Quote Reply
Re: [long327] Cache Page question In reply to
Understand that, there is no field under the Page to change the search weight...

</not a clue>
Quote Reply
Re: [Dinky] Cache Page question In reply to
Hi Dinky

When you click on "Page" column, you will be brought to
"Edit Page Column Definition" form. The last text box is "Search Weight".

Long

Last edited by:

long327: Apr 30, 2004, 12:45 AM
Quote Reply
Re: [long327] Cache Page question In reply to
Sorry, not there....
The last box is the form regex...
I tried adding 'weight' => "1" to the .def, but keep getting a syntax error...

</not a clue>
Quote Reply
Re: [Dinky] Cache Page question In reply to
That's weird (that's true, I will check it).

If you edit the def, the "Page" column should look like this. Please note there is no "," at the end of the last line 'weight' => '2'
Code:

'Page' => {
'file_max_size' => '',
'file_save_in' => '',
'file_save_scheme' => 'HASHED',
'file_save_url' => '',
'form_display' => '',
'form_size' => [
'30',
'6'
],
'form_type' => 'TEXTAREA',
'not_null' => '1',
'pos' => '3',
'regex' => '',
'type' => 'TEXT',
'weight' => '2'
},

Last edited by:

long327: Apr 30, 2004, 1:10 AM
Quote Reply
Re: [long327] Cache Page question In reply to
Oops, was forgetting to put the , after the entry before where I added the weight...
Works great, the whole doggone thing works outstanding, thanks for all your help!!!

</not a clue>
Quote Reply
Re: [long327] Cache Page question In reply to
Hi Long,

I think this thread is a great explanation of how to search a custom table (maybe it could be added to resources/Andy's site).

However, I think the modification to Search.pm would be much better done in a plugin.

In Reply To:

The problem is if the plugin is hooked to post search result, that result returned by search.pm is html formatted[/quote]

I think that you actually need the plugin as a pre hook. This is what I've done on my site - you can then just copy the new sub query that you have into the plugin and run this.

In the Plugin.pm file you'll need a sub:

sub search_results {
my (@args) = @_;
if (condition) {
GT::Plugins->action( STOP ); # this stops the regular Search.pm query sub from running.
#CONTENTS OF YOUR NEW QUERY SUB HERE
...
return $results;
} else {return @args;}
}

You may want to put the STOP line in an if statement if you only want your new search to work for certain conditions - otherwise you can remove the if statement and run it for all queries.

Laura.
The UK High Street
Quote Reply
Re: [afinlr] Cache Page question In reply to
Thank you again, Laura.

I am still not sure if it's possible without modifying the search.pm file to search custome table.

For my own specific needs, I want the search to be done like this (assuming we are using the pre hook):

1) First, search cached_page table, pass vaiable (linkID, summarized matches as description) to search.pm.

2) search links and category table by the main program. (here is the problem I don't know how it will handle it: most results returned from cached_page table (pool A) will not be in the results from links table (pool B, Pool A and B overlaps), the program has to query links table again to get other variables for those links in pool A such as URL, title etc for display. Apparently Search.pm won't do this. Alternatively, we can do this within the plugin, then pass them to the main program, but in this way, pool A will be overwritten. We don't want this to happen because we want to show to users the matched sentences which are not in pool B's description filed. If we use "Stop", then we cannot get cateogry results and some link result.

I hope I have made myself understood and hope you and others can figure out an answer to thoes questions.

Long
Quote Reply
Re: [long327] Cache Page question In reply to
Hi,

I'm not certain that I'm understanding yet (I haven't spent a lot of time analysing what your changes in the Search.pm file do) but I'm assuming that the query sub that you've put in the post above does exactly what you want? If so then you can use a plugin with this exact sub in it and the STOP line. That way the plugin will use your new sub instead of the one in the Search.pm file. This just means that you're not altering core code which will get overwritten in an update. It will do exactly what it is doing now - this is just a way of using plugins so that you don't change the core files.

If however, your changes to the Search.pm file are not doing what you want, I would need to investigate this more.

Laura.
The UK High Street
Quote Reply
Re: [afinlr] Cache Page question In reply to
Hi Laura,

Now I seem to understand what you mean. Stop the whole query sub, and put it into the plugin. That's wonderful, I've never though of it. Thanks.

I will give it a try.

Long
Quote Reply
Re: [long327] Cache Page question In reply to
Another question ref the cache page plugin...
When you build the pages, it gives you the site title and the LinkID for the <title> of the page... is there a way to put the link title in place of the LinkID? I have tried to use a global:

sub {
return $DB->table('Links')->select( { ID => $_[0]->{ID} })->fetchrow_hashref;
}

to pull the title from the original links installation, but no luck...
thanks

</not a clue>
Quote Reply
Re: [Dinky] Cache Page question In reply to
this will do:
Code:

sub {
my $id =shift;
my $db=$DB->table('Links');
my $rec=$db->get($id->{LinkID});
return $rec->{Title};
}

In your cache_page template, use the global name to pull up the title. e.g. if you give this global the name of "title", then use <%title%> to display it where you want.

Long