使用参数
Joomla在很多地方可以设置很多参数。每个扩展,都可以添加自己的参数或选项。
参数可以设置基本参数,比如,如果一个插件自动纠错,应该添加一些参数,让管理员设置纠错如何执行。要不要自动把首字母大写?要不要删除段首的空格?通过添加参数可以做到这些。
在XML中定义参数
在XML配置文件中,参数通过<config>
标签来添加。为插件添加参数和为组件、模块一样。
下面的例子显示一个字段集,命名为basic
,一个输入字段,命名为test
。这个字段允许管理员保存一个值,一遍以后再PHP代码中使用。
<config>
<fields>
<fieldset name="basic">
<field
name="test"
type="text"
defalut=''Hello World''
label="PLG_CONTENT_CH04TEST01_FIELD_LABEL_LABEL"
description="PLG_CONTENT_CH04TEST01_FIELD_LABEL_DESC"
/>
当使用Plugin Manager时,它会读取这个XML文件,自动转换为HTML,显示在编辑区域。
上面的例子是一个字段集和一个输入框。Joomla允许很多的字段集和表格字段。甚至可以自定义字段。比如,可以创建一个自定义的下拉框。
<fieldset name="basic">
字符集没有标签。Joomla自动为basic和advanced添加标签。也可以通过lable
参数自定义标签。如果没有lable值,将会自动填充为COM_PLUGINS_CUSTOMX_FIELDSET_LABEL
。这个语言字符串在com_plugin中定义了。
参数存在哪?如何存储的?
当使用Plugin Manager存储参数时,参数值存储在数据表#__extensions
中的params中,以Json的格式存储。当从数据库中读取后,JSON数据解码为JRegistry
对象,并绑定到插件对象上。这些是自动完成的。
更多字段类型
最通用的四种:text, textarea, list, radio。还有些复杂的,比如calendar
,combo
, color
,email
, password
。
例子,
<field
name="align"
type="list"
default="left"
label="PLG_CONTENT_CH04TEST01_FIELD_ALIGN_LABEL"
description="PLG_CONTENT_CH04TEST01_FIELD_ALIGN_DESC"
>
<option value="left">PLG_CONTENT_CH04TEST01_FIELD_ALIGN_OPTION_LEFT</option>
<option value="right">PLG_CONTENT_CH04TEST01_FIELD_ALIGN_OPTION_RIGHT</option>
<option value="center">PLG_CONTENT_CH04TEST01_FIELD_ALIGN_OPTION_CENTER</option>
</field>
下拉列表框通过<option>
标签,来显示选项。
在php文件中使用参数
在插件的php文件中,使用$this->params
这个对象,这是一个JRegistry
,包含一个get()
方法,参数名作为第一个参数,第二个参数是如果读取为空的时候的默认值。
public function onContentBeforeDisplay(
$context, &$row, &$params, $page = 0
)
{
$test = $this->params->get(′test′, ′Hello World′);
$row->title = $row->title . ′ [′ . $test . ′]′;
$row->text = $row->text . ′<p>[′ . $test . ′]</p>′;
}
$params
和 $this->params
的区别:
onContentBeforeDisplay()
有四个参数,第三个是$params
,也是一个JRegistry
对象。区别是, $this->params
包含本插件参数,$params
包含的是内容类型参数。比如,文件插件的参数就是Article Manager中的参数。
安全问题:
如果是调用个数值,可以做下强制转换
$integer = (int) $this->params->get(′integer′);
如果用的下拉列表,可以看看是不是在选项中
$value = $this->params->get(′color′);
if (in_array($value, array(′yellow′, ′red′, ′blue′)) == FALSE)
{
$value = ′yellow′;
}
一般情况下,Plugin Manager需要输入一个值,也有变通的方法输入多个值,用逗号把值分开。比如输入一组颜色
green,yellow, #ffcc00, #000,
然后再PHP中用explode
转换为一个数组
$list = $this->params->get(′list_from_textarea′);
$list = explode(′,′, $list);
但是,用户的输入一定要过滤,有可能有空格和回车
foreach ($list as $index => $value)
{
$value = trim($value);
if (empty($value))
{
unset($list[$index]);
continue;
}
$list[$index] = $value;
}
可以通过将multiple
属性设置为true来建立多种选择的下拉框
定义新的字段类型
Joomla的参数都是基于JForm
库,包含一组类,提供一种面向对象的方法来建立和验证表单。通过这个库可以方便的添加HTML表单而不用担心其显示样式。JForm库会自动渲染XML代码成Joomla风格的HTML,并且建议表单验证(基于验证规则)。
在Plugin Mananger中,不必操心渲染和验证部分。唯一需要做的是添加XML代码。
除了现有的字段类型,还可以自定义字段,基于JForm类,然后添加到表单中。比如,要添加一个下拉框,选项是自定义的,而不是静态的。
XML选项
假设要建立一个新的字段,加做testselect
。先需要建议一个相应的类JFormFieldTestselect
,放在插件的子目录field
中。
在XML中,通过type属性来使用新类型<feld type=″testselect″ ... />
<config>
<fields name="params">
<fieldset name="basic" addfieldpath="plugins/content/ch04test02/fields">
其中addfeldpath
变量保证JFrom库能够搜索到field
目录。
在自定义testselect
中,<option>
标签不用写。
在plugins/content/ch04test02/felds
子目录中,建议一个testselect.php
文件,
<?php
defned(′_JEXEC′) or die();
jimport(′joomla.form.formfeld′);
class JFormFieldTestselect extends JFormField
{
protected $type = ′Testselect′;
protected function getInput()
{
return ′′;
}
}
其中jimport()
函数用来加载JFormField
类。较新的Joomla版本中,这个不必须了。
然后新建一个子类JFormFieldTestselect
,其中$type
变量是新字段的名称。
方法getInput()
返回时间的HTML代码。
$options = array();
$options[] = JHTML::_('select.option', 'sample01', JText::_('JFORM_FIELDTYPE_TESTSELECT1_SAMPLE01'), 'value', 'text');
$options[] = JHTML::_('select.option', 'sample02', JText::_('JFORM_FIELDTYPE_TESTSELECT1_SAMPLE02'), 'value', 'text');
return JHTML::_('select.genericlist', $options, $this->name, 'class="inputbox"', 'value', 'text', $this->value, $this->name);
可以直接用HTML代码。最好使用JHTML
函数生成。变量$this->name
和$this->value
用来为表格元素增加正确的属性。
从数据库中获取数据
出来使用静态列表,还可以进一步的,通过数据库查询获得新的数据。
JFactory::getDbo()
方法可以获取数据库实例。为了适应不同的数据库,不要直接写SQL语句,而是使用对象方法。
protected function getInput()
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select($db->quoteName(array(′w.url′, ′w.title′)));
$query->from($db->quoteName(′#__weblinks′, ′w′));
$query->where($db->quoteName(′w.approved′).′ = 1′);
$query->order($db->quoteName(′w.title′));
$db->setQuery($query);
$options = array();
$rows = $db->loadObjectList();
if (!empty($rows))
{
foreach ($rows as $row)
{
$options[] = JHtml::_(′select.option′, $row->url, $row->title, ′value′, ′text′ );
}
}
$attribs = ′class=″inputbox″′;
return JHtml::_(′select.genericlist′, $options,$this->name, $attribs, ′value′, ′text′,$this->value, $this->name);
}
这个例子从#__weblinks
表中获取数据,通过选择标题来获取URL
为例能够使第三方开发者也能使用你的自定义字段,需要能够支持额外的XML参数。比如,你想方便的转换单项选择和多项选择,
<input type=″testselect″ multiple=″1″ size=″10″ />
其中multiple
默认是0,通过以下的方法,如果改为1,就能多项选择了。
通过$this->element[′multiple′]
来调用XML中的设置。
$multiple = 0;
$size = 3;
$attribs = 'class="inputbox"';
if (isset($this->element['multiple']))
{
$multiple= filter_var($this->element['multiple'], FILTER_VALIDATE_BOOLEAN);
}
if (isset($this->element['size']))
{
$size = (int) $this->element['size'];
}
if ($size < 3)
{
$size = 3;
}
下面就是加入到下拉框的属性里了。通过添加第四个变量到JHtml::_(′select.genericlist′)
的调用中,这个参数可以添加额外的HTML属性到select元素中。现在我们通过变量$attribs
动态的创建这些属性。这样就可以通过改变XML变量来改变HTML元素了。
$attribs = ′class=″inputbox″′;
if ($multiple == true)
{
$attribs .= ′ multiple=″multiple″′;
}
if ($size > 0)
{
$attribs .= ′ size=″′ . $size . ′″′;
}
s we
add some arguments to the XML:
<input type=″testselect″ multiple=″1″ size=″10″ />
The multiple argument defaults to 0 (false), however by changing it to 1 (true) we
can enable the multiselect behavior which follows below.
The argument size does nothing by default. When multiple is true however, the
size argument is used to determine the size of the multiselect box. If the size is smaller
than 3, it will be ignored and the size will be set to 3. If the size is larger than or equal to 3,
the size will be equal to the amount of options available.
$multiple = 0;
$size = 3;
if (isset($this->element[′multiple′])
{
$multiple = (bool) $this->element[′multiple′];
}
if (isset($this->element[′size′]))
{
$size = (int) $this->element[′size′];
if ($size < 3) $size = 3;
}
Now that the variables are prepared, we can add them to the dropdown attributes. We
do this by adding a fourth argument to the JHtml::_(′select.genericlist′)
call, which allows us to add additional HTML attributes to the select element. We now
dynamically construct these attributes as a variable $attribs, in order for the HTML
attributes to change depending on the given XML arguments.
$attribs = ′class=″inputbox″′;
if ($multiple == true)
{
$attribs .= ′ multiple=″multiple″′;
}
if ($size > 0)
{
$attribs .= ′ size=″′ . $size . ′″′;
}
return JHtml::_(′select.genericlist′, $options,
$this->name, $attribs, ′value′, ′text′,
$this->value, $this->name;
在一个XML配置文件中使用多个文件路径
在<fieldset>
标签中添加addfeldpath
属性是一种方式,来使JForm
库在搜寻字段类型时来查找这个目录。因为JForm
类用来渲染整个表格,所以,这种引入在整个表格周期都能用。比如:
<feldset name=″basic″
addfeldpath=″plugins/content/ch04test01/felds″>
</feldset>
<feldset name=″advanced″>
<feld type=″testselect″ ... />
</feldset>
不能为一个标签指定多个addfeldpath
,XML只添加第一个,第二个不会被添加
<feldset addfeldpath=″path1″ addfeldpath=″path2″ ...
为了添加多个路径,可以把一个添加到<felds>
标签,一个添加到<feldset>
标签,设置可以添加到实际需要它的<feld>
标签
<confg>
<felds addfeldpath=″path1″ ...
<feldset addfeldpath=″path2″ ...
<feld addfeldpath=″path3″ ...
当一个addfeldpath
变量添加到JForm
库时,新路径会被加入到path字符串的末尾。如果想要覆盖一个Joomla核心中已经存在的字段类型,最好是在Joomla启动过程中尽早添加,比如通过一个System Plugin在onAfterInitalise中添加。
JFormHelper::addFieldPath($path);
如果字段类型找不到怎么办?默认会被转换成text
类型。
小结
这章讨论了插件参数,如果在XML配置文件中定义,如果在插件php文件中使用。也学习了如果自定义JForm使用新的插件类型。通过前四章,可以写一个插件,完成安装,更新和自定义表单。虽然没有针对特定的场景。