Home_Page sep Recent_Changes sep Feed_back sep Online_Help sep Search:
Any language locale supported by your server can be used to create link words. (in Internationalization_and_localization)
single_word_linking  right Referencing_Pages, Similar_Pages, Page_Activity
Chiq_Chaq – your friendly free_site
(with full online_help)

New Pages:

Popular Pages:

  1. Home_Page
  2. New=
  3. Installation_Problems
  4. Free_Site
  5. Chiq_Chaq

Random Pages:

Search this site:

You can edit this side_bar!

Hi all,

I had a need to allow for single word linking because I am using chiq_chaq for a glossary application where single words are very common. Through my totally amateur hacking, I've been able to get chiq_chaq working to allow single word links by using the relatively standard [[doublebrackets]] seen in other wikis.

Before you look at my code, you may want to demo this functionality for your self. I've set up a demo here:


I imagine there are much more efficient ways to do what I've done, but then again I'm not really a programmer – just a hacker. If you can think of more efficient ways to do this, feel free to add comments.

To implement single word linking try the following:

In Link.pm:

  1. add two new variables near "Link Structure" line 25 as follows"

# Link structure:
my $free_link_word = "[-,.()' _0-9A-Za-z]"; # new variable
my $link_word = '([^\W_]|\')+';
our $free_link_pattern = "($free_link_word)+"; # new variable
our $link_pattern = "$link_word(_$link_word)+";

  1. Immediately after sub internal_link() add the following new sub routine:

sub free_internal_link {
    my ($title) = @_;
    my $trailer;
    my $tooltip;
    # remove [[ ]] brackets
    $title =~ s/\[\[|\]\]//g;
    my $anchor = $title;
    my $attr = ' ' . $tag_attributes if $tag_attributes;
    my $dir = '‏' if $main::right_to_left; # TODO: ugly
    $anchor =~ s/_/ /g if ($spaces_in_anchor);
    if (!page_exists($title)) {
        return $anchor if ($skip_empty_pages);
        $trailer = '<sup>?</sup>';
        $tooltip = qq( title="$empty_tooltip") if ($empty_tooltip ne '');

    qq(<a href="$pre_url$title$post_url" class="cclink"$attr$tooltip>$anchor$trailer$dir</a>);

  1. Change sub link_implicitly() as follows:

sub link_implicitly {
    local ($_) = shift;
    $tag_attributes = shift;
#    replace_outside_tags($link_pattern, \&internal_link);
    replace_outside_tags($link_pattern, \&internal_link, 'standard'); # <-- be sure to add the new argument 'standard'
    # added to allow single word links...
    replace_outside_tags($free_link_pattern, \&free_internal_link,'free');
    $tag_attributes = undef;
    return $_;

  1. Change sub replace_outside_tags() as follows:

sub replace_outside_tags {
    my ($pattern, $replacement_func, $link_type) = @_;  # <-- be sure to capture the new argument
    my $tag  = qr(<[^>]*>);
    my $link = qr((?i)<a[^>]+href\s*=.+?</a>);
    my $code = qr(((?i)<(pre|span)[^>]+class\s*=\s*"?cccode["\s>](?:\n|.)*?</\2>));
#    s!$code|($link)|($tag)|($pattern)!$1||$3||$4||&$replacement_func($5)!egs;
    if ($link_type eq 'free'){
    } else {


  1. In sub convert_to_link_pattern() comment out the $link pattern condition towards the bottom of the sub:

sub convert_to_link_pattern {
    $_[0] =~ s/^\s+//;
    $_[0] =~ s/\s+$//;
    $_[0] =~ s/"/''/g;
    local $_ = $_[0];
    return 1 if (/^$link_pattern$/);

    my $word_separators = '_ \-';
    s/[^\'\w$word_separators]//g;                  # delete illegal characters
    $_ = join('_', split(/[$word_separators]+/)); # seperate words with _
#    return 0 if (!/^$link_pattern$/);
    $_[0] = $_;
    return 1;

In chiq.pl

  1. Change sub show_search() so it looks like this...

sub show_search {
    my ($query, $titles, $pages) = @_;
    my $html = read_skin('search') or return err("Error reading 'search' skin in $skin_dir: $!");

    my $attr = 'target="_blank"' unless $single_browse_window;

    # format single word result strings..
    foreach my $page (@$pages){
        if (!($page =~ /_/)){
            $page = "[[$page]]\n";

    foreach my $title (@$titles){
        if (!($title =~ /_/)){
            $title = "[[$title]]\n";

    fill_in( $html,
         'words'        => $query,
         'search_box'   => link_implicitly("[\?$query]"),
         'titles_num'   => scalar(@$titles),
         'contents_num' => scalar(@$pages),
         'titles'       => link_implicitly( join("<br>\n", @$titles), $attr ),
         'contents'     => link_implicitly( join("<br>\n", @$pages), $attr ),
        } );

I'm pretty sure that's all the changes that are needed. If you have any problems, please put them here, I'll check back or you can email me at mpaler at dontjinxit dot com.

Good luck,

Yonat_Sharon (Wednesday, April 07, 2004, 00:37):
Thanks! I hope I'll have time to play with it soon.
I have a much simpler solution that is consistent with the way Chiq Chaq works right now:

just change the line

our $link_pattern = "$link_word(_$link_word)+";

in Link.pm to

our $link_pattern = "($link_word)?(_$link_word)+";

and you can use a leading underscore for single word links like this : _Eli.

Cool, Thanks!
Using the second code fix:

our $link_pattern = "($link_word)?(_$link_word)+";

did not work for me. After modifying Link.pm with that I got the following when I tried to load my Chiq Chaq Home Page:

Chiq_Chaq Error
Illegal page title: Home_Page

Yeah...I tried it too and all my typical words_with_underscore got doubled up like this: words_with_underscorewords_with_underscore

Some questions...
Will this solution allow for both link types? (ie single and multiple with underscoress)
Will this solution work with search results pages?

Created using Chiq_Chaq sep Terms_of_Use sep User_Privacy