致 OP:您没有正确描述配置格式,XML 片段会帮助我们。因为它是您可能必须修改下面的解决方案以匹配您的格式。
我假设了以下格式:
<conf>
<option><name>configuration1</name><value>string1 modified</value></option>
<option><name>configuration2</name><value>string2 re-modded</value></option>
<option><name>configuration3</name><value>string3</value></option>
</conf>
处理这种格式的代码是:
#!/usr/bin/perl
use strict;
use warnings;
use CGI qw( -nosticky -utf8 :standard form );
use XML::LibXML;
my $CONF="/web/data/conf.xml"; # or wherever your XML is located
# dispatch table, action => code to process it
my $dispatch= { display => \&display_conf,
edit => \&display_edit_form,
save => \&save_edits,
};
# action is "what to do"
my $action= param( 'action') || 'display';
$dispatch->{$action}->() || exit_error( "wrong action");
exit;
# load the XML and build a table to display it
sub display_conf
{ my $conf= XML::LibXML->load_xml( location => $CONF);
my $content;
foreach my $option ($conf->findnodes( '/conf/option'))
{ $content .= Tr( td( $option->findvalue( './name')),
td( $option->findvalue( './value'))
);
}
$content= table( $content);
# add a link to the edit form
$content .= p( a({ href => url() . '?action=edit' }, 'edit'));
output( $content);
}
# load the XML and build a form that will let you edit it
sub display_edit_form
{ my $conf= XML::LibXML->load_xml( location => $CONF);
my $content;
foreach my $option ($conf->findnodes( '/conf/option'))
{ $content .= Tr( td( $option->findvalue( './name')),
td( input( { type => "text", size => 40,
name => $option->findvalue( 'name'),
value => $option->findvalue( './value')}
)
)
);
}
$content= table( $content);
$content= form( { action => url() },
hidden( { name => 'action', value => 'save', override => 1 }),
$content,
submit( 'Save'),
);
output( $content);
}
# load the XML, go through all options, update the value from the form,
# save the XML, display it value, from the form
sub save_edits
{ my $conf= XML::LibXML->load_xml( location => $CONF);
foreach my $option ($conf->findnodes( '/conf/option'))
{ my $new_value= param( $option->findvalue( './name'));
my( $value_node)= $option->findnodes( './value');
$value_node->removeChildNodes();
$value_node->appendText( $new_value);
}
$conf->toFile( $CONF);
display_conf();
}
# placeholder,
sub exit_error
{ my $message= shift;
print header(), p($message);
}
# output subs, load the template, inject the content and output (with header)
sub output
{ my $content= shift;
print header(), fill_in_string( template(), content => $content );
}
sub fill_in_string
{ my( $template, %param)= @_;
$template=~ s{<<(\w+)>>}{$param{$1}}g;
return $template;
}
sub template
{ return join '', <DATA>; }
# template, very simple
__DATA__
<html>
<head>
<title>Configuration Editor</title>
</head>
<body>
<h1>Configuration Editor</h1>
<h2>Configuration</h2>
<<content>>
</h2>
</body>
</html>
部署:将代码放在可以作为 CGI 运行的地方,并确保conf.xml
可以被 Web 服务器读取和写入。将它放在网络树之外可能会更好。
这在某种程度上是史前 Perl。CGI 被广泛认为是过时的,Perl 中提供了更多现代和花哨的选项。如果您的配置比键/值列表更复杂,如果您想为每个字段提供自定义帮助,或者如果您需要使用更复杂的模板来符合您公司的外观,那么像 Dancer 或 Mojolicious 这样的 Web 框架会比上面的简单解决方案更适合。
OTOH 它可以工作,我仍然是这样编写很多小工具的,这些工具有一些内部用户并且在 UI 方面不需要太多。
对于那些建议对不熟悉 Perl 的人来说这太复杂而无法执行的人,你们走好了!这不是航天科技。正是这种让人们开始使用 Perl 的代码,我们为什么不帮助编写它呢?这实际上是The Reluctant Perl Programmer的完美例证。