summaryrefslogtreecommitdiff
path: root/doc/todo/Add_a_plugin_to_list_available_pre-processor_commands.mdwn
blob: 3ba0202a0f30c7b94eb4aec61d4caa511df3361a (plain)

I've found myself wanting to know which [[plugins]] are switched on so I know which pre-processor commands I can use. The attached [[patch]] adds a new plugin that generates the list of available plugins. -- [[Will]]

Good idea, I do see a few problems:

  • preprocessor directives do not necessarily have the same name as the plugin that contains them (for example, the graphviz plugin adds a graph directive). Won't keys %{IkiWiki::hooks{preprocess}} work?

Er, yeah - that's a much better solution. :) -- and done

  • "listplugins" is a bit misnamed since it only does preprocessor directives.

Yes. Initially this was going to list all enabled plugins. Then when searching for enabled plugins I changed my mind and decided that a list of pre-processor directives was more useful. I'll fix that too. -- changed to listpreprocessors

  • comment was copied from version plugin and still mentions version :-)

:-) -- fixed

  • Seems like [[ikiwiki/formatting]] could benefit from including the list.. however, just a list of preprocessor directive names is not the most user-friendly thing that could be put on that page. It would be nice if there were also a short description and maybe an example of use. Seems like the place to include that info would be in the call to hook(). (Maybe adding that is more involved than you want to go though..)

--[[Joey]]

Adding a whole new hook for a usage example is more effort than I wanted to go to. I was thinking of either:

  • Adding a configuration for a wiki directory. If a matching page is in the specified wiki directory then the plugin name gets turned into a link to that page
  • Adding configuration for an external URL. Each plugin name is added as a link to the plugin name appended to the URL.

The first option is easier to navigate and wouldn't produce broken links, but requires all the plugin documentation to be local. The second option can link back to the main IkiWiki site, but if you have any non-standard plugins then you'll get broken links.

Hrm. After listing all of that, maybe your idea with the hooks is the better solution. I'll think about it some more. -- [[Will]]

I started implementing the hook based solution, and decided I didn't like it because there was no nice way to rebuild pages when the preprocessor descriptions changed. So instead I assumed that the the [[plugins]] pages would be moved into the underlay directory. This plugin then uses an inline directive to include those pages. You can use the inline parameter to decide if you want to include all the descriptions or just the titles. There is also an option to auto-create default/blank description pages if they are missing (from a template). As preprocessor commands don't list unless they have a description page, auto-creation is enabled by default.

There are three new templates that are needed. These are for:

  • The auto-created description pages are generated from preprocessor-description.tmpl.
  • When only pre-processor names are listed, the listpreprocessors-listonly.tmpl template is used.
  • When pre-processor descriptions are included inline, the listpreprocessors-inline.tmpl template is used.

-- [[Will]]

Here is the main listpreprocessors plugin. (Note, because this has double square brackets in the source, it isn't quite displaying correctly - look at the page source for details.) New template files follow:

#!/usr/bin/perl
# Ikiwiki listpreprocessors plugin.
package IkiWiki::Plugin::listpreprocessors;

use warnings;
use strict;
use IkiWiki 2.00;

sub import { #{{{
	hook(type => "getsetup", id => "listpreprocessors", call => \&getsetup);
	hook(type => "preprocess", id => "listpreprocessors", call => \&preprocess);
	hook(type => "refresh", id => "listpreprocessors", call => \&refresh);
} # }}}

sub getsetup () { #{{{
	return
		plugin => {
			safe => 1,
			rebuild => undef,
		},
		preprocessor_description_dir => {
			type => "string",
			description => "The ikiwiki directory that contains plugin descriptions.",
			safe => 1,
			rebuild => 1,
		},
		preprocessor_description_autocreate => {
			type => "boolean",
			description => "Should pre-processor command descriptions be automatically created from a template.",
			safe => 1,
			rebuild => 1,
		},
} #}}}

sub gendescription ($$) { #{{{
	my $plugin=shift;
	my $page=shift;
	my $file=$page.".".$config{default_pageext};
	my $template=template("preprocessor-description.tmpl");
	$template->param(page => $page, plugin => $plugin);
	writefile($file, $config{srcdir}, $template->output);
	if ($config{rcs}) {
		IkiWiki::rcs_add($file);
	}
} #}}}

sub refresh () { #{{{

	if (defined $config{preprocessor_description_autocreate} && ! $config{preprocessor_description_autocreate}) {
		return;	# create pages unless they explicitly ask us not to
	}

	if (!defined $config{preprocessor_description_dir}) {
		$config{preprocessor_description_dir} = "ikiwiki/plugin/";
	}
	
	my @pluginlist = sort( keys %{ $IkiWiki::hooks{preprocess} } );
	my %pluginpages;

	if (@pluginlist) {
		my ($plugin,$page);
		
		foreach $plugin (@pluginlist) {
			$pluginpages{$plugin} = $config{preprocessor_description_dir} . $plugin;
		}

		if ($config{rcs}) {
			IkiWiki::disable_commit_hook();
		}
		
		while (($plugin,$page) = each %pluginpages) {
			gendescription($plugin,$page);
		}
		
		if ($config{rcs}) {
			IkiWiki::rcs_commit_staged(
				gettext("automatic pre-processor description generation"),
				undef, undef);
			IkiWiki::enable_commit_hook();
		}
	}
} #}}}

sub preprocess (@) { #{{{
	my %params=@_;
	
	if (!defined $config{plugin_description_dir}) {
		$config{plugin_description_dir} = "ikiwiki/plugin/";
	}
	
	my @pluginlist = sort( keys %{ $IkiWiki::hooks{preprocess} } );
	foreach my $plugin (@pluginlist) {
		$plugin = $config{plugin_description_dir} . $plugin;
	}
	my $pluginString = join (' or ', @pluginlist);
	
	my $result = "[[!inline pages=\"$pluginString\" feeds=\"no\" show=0 sort=\"title\"";
	
	if (defined $params{inline}) {
		$result .= ' template=\"listpreprocessors-listonly\" archive="yes"';
	} else {
		$result .= ' template=\"listpreprocessors-inline\" archive="no"';
	}
	
	$result .= "]]";
	
	return IkiWiki::preprocess($params{page}, $params{destpage}, 
		IkiWiki::filter($params{page}, $params{destpage}, $result));
} # }}}

1

This is what I was using for listpreprocessors-inline.tmpl:

<div class="listpreprocessorsinline">

<div class="inlineheader">

<span class="header">
<a href="<TMPL_VAR PAGEURL>"><TMPL_VAR TITLE></a>
</span>

</div><!--.inlineheader-->

<div class="inlinecontent">
<TMPL_VAR CONTENT>
</div><!--.inlinecontent-->

</div><!--.listpreprocessorsinline-->

This is what I was using for listpreprocessors-listonly.tmpl:

<p class="listpreprocessors"><a href="<TMPL_VAR PAGEURL>"><TMPL_VAR TITLE></a></p>

This is what I was using for preprocessor-description.tmpl:

The <TMPL_VAR plugin> preprocessor command currently has no description.

Maybe you should edit this page to add one.