0byt3m1n1
Path:
/
data
/
applications
/
aps.bak
/
coppermine
/
1.5.12-0
/
standard
/
htdocs
/
docs
/
nl
/
[
Home
]
File: dev_plugin_steps.htm
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr"> <head> <title>Creating plugins: step by step - Coppermine Photo Gallery - Documentation & Manual</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="language" content="en" /> <meta name="copyright" content="Coppermine dev team" /> <meta name="description" content="" /> <meta http-equiv="Content-Style-Type" content="text/css" /> <meta name="MSSmartTagsPreventParsing" content="true" /> <meta http-equiv="imagetoolbar" content="no" /> <!-- SVN version info: Coppermine version: 1.5.12 $HeadURL: https://coppermine.svn.sourceforge.net/svnroot/coppermine/trunk/cpg1.5.x/docs/nl/dev_plugin_steps.htm $ $Revision: 8154 $ --> <link rel="stylesheet" type="text/css" href="../style/style.css" media="all" /> <link rel="stylesheet" type="text/css" href="../style/screen.css" media="screen" /> <link rel="stylesheet" type="text/css" href="../style/print.css" media="print" /> <link rel="stylesheet" type="text/css" href="../js/fullsize/fullsize.css" media="screen" /> <link rel="shortcut icon" href="../favicon.ico" /> <script src="../js/jquery.js" type="text/javascript"></script> <script src="../js/jquery.treeview.js" type="text/javascript"></script> <script src="script.js" type="text/javascript"></script> <script src="../js/fullsize/jquery.fullsize.minified.js" type="text/javascript"></script> <script type="text/javascript"> $(function(){ $("img").fullsize(); }); </script> </head> <body> <h1 id="docheader">Coppermine Photo Gallery v1.5.x: Documentation and Manual</h1> <div id="toc"> <a href="toc.htm">Table of Contents</a> </div> <div id="doc_en_only">No translation available</div> <a name="steps"></a><h1>Creating plugins: step by step<a href="#steps" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h1> This page is meant to give plugin authors step-by-step directions how to create a plugin. It assumes that you have read <a href="dev_plugins.htm#plugin_writing">Plugin writing for Coppermine</a> as an introduction. <div class="indent"> <a name="steps_template_plugin"></a><h2>Getting started with the plugin template<a href="#steps_template_plugin" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h2> The Coppermine developers understand that it might be asked a bit much to come up with a working plugin from scratch, that's why we're providing an empty plugin template that you can use to start to come up with a plugin of your own. You will find the plugin template as an attachment inside the docs folder, so these are the steps to get you going: <div class="indent"> <a name="steps_extract_template"></a><h3>1. Extract the plugin template<a href="#steps_extract_template" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> As suggested above, the plugin template comes as an attachment inside the documentation folder, so you can simply download it by clicking <a href="../tutorial/cpg1.5.x_plugin_template_v1.0.zip">here</a>. Alternatively, you can <a href="https://sourceforge.net/projects/coppermine/files/Plugins/1.5.x/cpg1.5.x_plugin_template_v1.0.zip/download" rel="external" class="external">get it from the download repository at sourceforge.net</a>. After downloading, extract the content of the archive into a temporary folder. As an example, we'll assume that you have extracted it to <tt class="filename">c:\temp\</tt>, so you should have a sub-folder <tt class="filename">c:\temp\template\</tt> <a name="steps_pick_name"></a><h3>2. Choose a name<a href="#steps_pick_name" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> Pick a name for your plugin. It's mandatory <strong>not</strong> to skip this step - you mustn't leave the name "template". Please refer to <a href="dev_plugins.htm#plugin_writing_preparation_name">Choose a name</a> for details. It's important that your plugin name is meaningfull and doesn't contain to many characters (consider 20 characters as a maximum). As an example, we'll assume that our plugin will brew coffee, that's why we'll refer to it on this page as <tt class="code">coffee_maker</tt>. <a name="steps_rename_folder"></a><h3>3. Rename the folder<a href="#steps_rename_folder" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> Rename the plugin template inside the temporary folder from <tt class="filename">c:\temp\template\</tt> to the name you have chosen as a short name for your plugin (e.g. <tt class="filename">c:\temp\coffee_maker\</tt> in our example here) <a name="steps_rename_file_content"></a><h3>4. Rename the placeholders inside the files<a href="#steps_rename_file_content" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> The plugin template contains several PHP-files already. In this step you have to loop through <strong>all</strong> those files and replace the placeholder word <tt class="code">template</tt> with the name you have chosen (e.g. <tt class="code">coffee_maker</tt> in our example). To accomplish this it's advisable to use an editor that can replace a string in various files at once; both tools that are capable to loop through all files within a particular folder (see <a href="dev_package.htm#packaging_steps_loop_through_files">Replace version number in all files</a>) as well as advanced <a href="dev_tools.htm#dev_tools_editor">plain text editors</a> like Notepad++ can do this.<br /> Don't forget the english language file inside the lang-subfolder ( <tt class="filename">c:\temp\coffee_maker\lang\english.php</tt>). <div class="cpg_example"> <table border="0" cellspacing="0" cellpadding="0" class="cpg_zebra"> <tr> <th valign="top" class="tableh1" colspan="2"> The screenshots show the dialogs in Notepad++ as examples. Click on the thumbnails to enlarge the screenshots.<br /> </th> </tr> <tr> <td valign="top"> <img src="images/replace_in_files1.png" border="0" width="143" height="120" alt="" longdesc="images/replace_in_files1.png" /> </td> <td valign="top"> <img src="images/replace_in_files2.png" border="0" width="181" height="120" alt="" longdesc="images/replace_in_files2.png" /> </td> </tr> <tr> <td valign="top"> The first screenshot above shows the dialog with all relevant files opened inside the editor. Click on the button "Replace in all open Documents" to perform the replacement. </td> <td valign="top"> The screenshot at the right shows another possible option in Notepad++, where you can perform a replace operation on particular files within a given folder. This is the most elegant and recommended solution for bigger replacement operations. </td> </tr> </table><br /> Please note that the above screenshots have been added as examples. Coppermine is not afiliated with Notepad++, nor do we support that particular application. However, we recommend it! </div> <a name="steps_copy_to_target"></a><h3>5. Copy the new plugin folder to the target<a href="#steps_copy_to_target" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> Inside your temporary folder ( <tt class="filename">c:\temp\</tt>) you should by now have a unique plugin based on the plugin template that is ready to be modified further by you. If you want to test it right away, copy your new custom plugin to the plugin folder of your Coppermine gallery (as suggested in <a href="plugins.htm#plugin_manager_upload_ftp">the "regular" plugin documentation</a>). As your custom plugin doesn't do anything yet (remember: the plugin template is just an empty shell to get you going easily), you will probably want to edit your plugin further, so you should copy it to the plugin folder of your testbed (if you have one) and continue there. <div class="cpg_example">For the sake of this article we'll assume that your local testbed or the mirror that corresponds to the files on your webserver resides at <tt class="filename">c:\mysite\</tt>. Therefore, the plugin folder would be <tt class="filename">c:\mysite\plugins\</tt> and the example plugin that we will refer to in this article will reside in <tt class="filename">c:\mysite\plugins\coffee_maker\</tt>.</div> <br clear="all" /> <br clear="all" /> </div> <a name="steps_config"></a><h2>Creating a config record for your plugin<a href="#steps_config" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h2> This section is assuming you have done as suggested above: that you're using the plugin template and that you have renamed both the plugin folder as well as all placeholders labelled "template" with the short name of your plugin. In this example, we'll asume the plugin name to be <tt class="code">coffee_maker</tt>. How the code of the config screen is composed is being explained in <a href="dev_plugin_api.htm#plugin_api_tutorial_config">Adding a config section to your plugin</a> in case you want to figure out what actually happens on the config screen. However, that it's not really necessary to read that section up - you should get away with just following the steps below.<br /> For our example plugin we'll assume that you only will have a handfull of config settings, so we'll use Coppermine's already existing config table and populate that with additional records to store our custom plugin config settings as well. <div class="indent"> <a name="steps_config_option_type"></a><h3>1. Decide for an option type<a href="#steps_config_option_type" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> First, you need to determine of what type the config option will be: <ul> <li>Checkbox</li> <li>Radio button</li> <li>Dropdown (option list) with one selectable item</li> <li>Dropdown (option list) with multiple selectable items</li> <li>Text input field (one line) for numerical input (integers)</li> <li>Text input field (one line) for input of any kind of text (not just numbers)</li> <li>Text input field (multiple lines, <abbr title="also known as">aka</abbr> textarea)</li> </ul> Depending on this decision you will need different language strings and you will need to apply different piece of code for the actual config screen. For now, just decide on one option and keep that in mind throughout the rest of the process. If you assistance in making up your mind, it's recommended to take a look at the paragraph about <a href="dev_coding.htm#dev_coding_usability_forms">forms</a> within the <a href="dev_coding.htm#dev_coding_usability">usability section</a> of the <a href="dev_coding.htm#dev_coding">coding guidelines</a> for Coppermine. <div class="cpg_example">For the sake of brevity, we will use a checkbox in the example boxes below</div> <a name="steps_config_name"></a><h3>2. Choose a record name<a href="#steps_config_name" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> Choose a short yet meaningfull name for your config option. Avoid cryptic abbreviations, only use lowercase alphanumerals and the underscore. <div class="cpg_example">If your plugin's name is <tt class="code">coffee_maker</tt> and your config option is meant to toggle an option that determines if the coffee will be served with or without an extra donut, we could be calling the option simply <tt class="code">donut</tt>. However, that may lead to misunderstandings or double definitions, that's why it's advisable to prefix the name of the config record with the words <tt class="code">plugin</tt> followed by the plugin's short name <tt class="code">coffee_maker</tt>. Finally, let's separate the words with underscores for better readability, so the option's record name would be <tt class="code">plugin_coffee_maker_donut</tt>, which is what we'll use in the following examples.</div> <div class="cpg_message_info">Keep in mind that the overall length of the record name mustn't exceed 40 characters! If you need longer names, you can not use Coppermine's config table to store your records in - you will have to create a table of your own.</div> <a name="steps_config_install"></a><h3>3. Create the record during plugin install<a href="#steps_config_install" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> During the install of the plugin we need to perform the database query once to create the needed record. To accomplish that, edit the codebase file that contains the actual plugin code (e.g. <tt class="filename">c:\mysite\plugins\coffee_maker\codebase.php</tt>) with a plain text editor, find <tt class="code">// Add the config options for the plugin</tt> within the function that determines the additionmal actions during the install of your custom plugin. Below that (into a line of it's own), enter <pre class="cpg_code code">cpg_db_query("INSERT IGNORE INTO {$CONFIG['TABLE_CONFIG']} (`name`, `value`) VALUES ('<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with in the previous step">plugin_coffee_maker_donut</span>', '<span style="color:red;font-weight:bolder;" title="Replace this with the default value for your config option">0</span>')");</pre> In the line above you of course have to edit the section <span style="color:orange;font-weight:bolder;">highlighted in orange</span> - that section needs to correspond to the config record name that you have chosen in the previous step. Additionally, you have to determine the default value of the config option (<span style="color:red;font-weight:bolder;">highlighted in red</span> in the line above). <a name="steps_config_uninstall"></a><h3>4. Create the uninstall query<a href="#steps_config_uninstall" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> You have to make sure that your plugin doesn't leave needless config records behind if it should get uninstalled in the future, that's why you need to come up with a query that will delete the config record, similar to the step above where you created the config record. To accomplish that, edit the codebase file that contains the actual plugin code (e.g. <tt class="filename">c:\mysite\plugins\coffee_maker\codebase.php</tt>) with a plain text editor, find <tt class="code">// Delete the plugin config records</tt> within the function that determines the additionmal actions during the uninstall of your custom plugin. Below that (into a line of it's own), enter <pre class="cpg_code code">cpg_db_query("DELETE FROM {$CONFIG['TABLE_CONFIG']} WHERE name = '<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_donut</span>'");</pre> In the line above you of course have to edit the section <span style="color:orange;font-weight:bolder;">highlighted in orange</span> in a similar manner as for the install - that section needs to correspond to the config record name that you have chosen when you decided for a plugin record name. <a name="steps_config_defaults"></a><h3>5. Specify the scope of your config record<a href="#steps_config_defaults" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> As suggested in <a href="dev_plugin_api.htm#plugin_api_tutorial_config_defaults">tutorial section that explains how to add config options</a> you need to determine on the page that actually composes the config page (<tt class="filename">c:\mysite\plugins\coffee_maker\admin.php</tt>) for your plugin what the scope of your config option will be, i.e. what config field type you have determined above and what the minimum and maximum value will be. To accomplish this, edit the file <tt class="filename">admin.php</tt> in your custom plugin folder (not the file <tt class="filename">admin.php</tt> in Coppermine's root folder; that file has only been named in analogy) with a plain text editor. Find <tt class="code"> $sanitization_array = array(</tt> and add below (in a line of it's own) <pre class="cpg_code code">'<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_donut</span>' => array(<span style="color:red;font-weight:bolder;">'type' => 'checkbox', 'min' => '0', 'max' => '1'</span>),</pre> Again, you need of course to edit the section <span style="color:orange;font-weight:bolder;">highlighted in orange</span> in the line above in a similar manner as for the install and the other sections above - that section needs to correspond to the config record name that you have chosen when you decided for a plugin record name.<br /> Additionally, you have to determine the scope of the config option using the section <span style="color:red;font-weight:bolder;">highlighted in red</span> in the line above. The table below explains what you need to replace depending on your choice of option type in the initial step "<a href="#steps_config_option_type">Decide for an option type</a>". This is basically the same table as in <a href="dev_plugin_api.htm#plugin_api_tutorial_config">Adding a config section to your plugin</a> <table border="0" cellspacing="0" cellpadding="0" width="100%" class="cpg_zebra"> <tr> <th valign="top">option type</th> <th valign="top">scope</th> <th valign="top">Usage (range)</th> <th valign="top">Parameters</th> <th valign="top">Example</th> </tr> <tr> <td valign="top"> <ul> <li>Checkbox</li> <li>Radio button</li> <li>Dropdown (option list) with one selectable item</li> </ul> </td> <td valign="top">checkbox</td> <td valign="top">Radio buttons and checkboxes with the values of the individual fields set to integers. The difference lies in the way that browsers handle empty checkboxes: if a checkbox is not ticked, there is no data submit with the form, just as if the checkbox wasn't there in the first place. This can cause issues if you explicitely empty a checkbox. The type 'int' can't handle this, but the type 'checkbox' can.</td> <td valign="top"> <ul> <li>'min' -> minimum value</li> <li>'max' -> maximum value</li> </ul> </td> <td valign="top"><pre class="smallcode">'plugin_coffee_maker_donut' => array('type' => 'checkbox', 'min' => '0', 'max' => '1'),</pre></td> </tr> <tr> <td valign="top"> <ul> <li>Text input field (one line) for numerical input (integers)</li> </ul> </td> <td valign="top">int</td> <td valign="top">Text input fields where only integers are allowed</td> <td valign="top"> <ul> <li>'min' -> minimum value</li> <li>'max' -> maximum value</li> </ul> </td> <td valign="top"><pre class="smallcode">'plugin_coffee_maker_lumps' => array('type' => 'int', 'min' => '0', 'max' => '9'),</pre></td> </tr> <tr> <td valign="top"> <ul> <li>Text input field (one line) for input of any kind of text (not just numbers)</li> <li>Text input field (multiple lines, aka textarea)</li> </ul> </td> <td valign="top">raw</td> <td valign="top">Use this for text input fields where you expect other content than integers - you can sanitize the input further using the parameter for this field.</td> <td valign="top"> <ul> <li>'regex_ok' -> <a href="dev_superglobals.htm#superglobals_sanitization_howto_regex">regular expression</a> that the submit data needs to match against</li> </ul> </td> <td valign="top"><pre class="smallcode">'plugin_coffee_maker_customer_name' => array('type' => 'raw', 'regex' => '/^[A-Za-z ]+$/'),</pre></td> </tr> <tr> <td valign="top"> <ul> <li>Dropdown (option list) with multiple selectable items</li> </ul> </td> <td valign="top">array</td> <td valign="top">Use this for an array of possible results that comes from one field, separated with a particular delimiter</td> <td valign="top"> <ul> <li>'regex_ok' -> <a href="dev_superglobals.htm#superglobals_sanitization_howto_regex">regular expression</a> that the submit data needs to match against, similar to the examples given above for the type 'regex'</li> <li>'delimiter' -> character that is being used to delimit one array element from the other inside the string, e.g. a slash</li> </ul> </td> <td valign="top"><pre class="smallcode">'plugin_coffee_maker_ingredients' => array('type' => 'array', 'regex' => '/^[A-Za-z ]+$/', 'delimiter' => '|'),</pre></td> </tr> </table> As you can see in the table above, the scope selection "checkbox" does not only apply for the form field item checkbox, but as well for radio buttons and select dropdowns with one selectable item. Subsequently, if you plan to implement a radion button with three possible selections (e.g. for a selector that let's visitors choose the strength of their coffee from "weak" to "normal" to "strong"), the scope definition would be something like <pre class="cpg_code code">'<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with">plugin_coffee_maker_strength</span>' => array(<span style="color:red;font-weight:bolder;">'type' => 'checkbox', 'min' => '0', 'max' => '2'</span>),</pre> with the possible options "0" corresponding to "weak", "1" to "normal" and "2" to "strong" (but we're going to determine that in a later step; for now, we'll just set the possible number of options to choose from). <a name="steps_config_form_options"></a><h3>6. Populate form options<a href="#steps_config_form_options" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> The radio buttons, checkboxes and select dropdowns need to be populated with values based on the corresponding values. That's why you need to keep on editing <tt class="filename">c:\mysite\plugins\coffee_maker\admin.php</tt>, find <pre class="cpg_code code">// Set the option output stuff </pre> and add below it into a line of it's own a small code block that determines the state of the radio button, checkbox or select dropdown. The code differs slightly, depending on the number of possible states: a checkbox can only have two states (checked or not checked). A radio buttons can have two or more states.<br /> For our example from above that is meant to create a checkbox that toggles on or off wether the coffee will be served with a donut or not, the code you would have to add would be: <pre class="cpg_code code">if ($CONFIG['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_donut</span>'] == '1') { $option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_donut</span>'] = 'checked="checked"'; } else { $option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_donut</span>'] = ''; }</pre> Once more, you need of course to edit the section <span style="color:orange;font-weight:bolder;">highlighted in orange</span> in the line above in a similar manner as for the install and the other sections above - that section needs to correspond to the config record name that you have chosen when you decided for a plugin record name.<br /> For a radio button (we'll use the other example from above that determines the strength of the coffee with three possible options to choose from), the corresponding code would be <pre class="cpg_code code">if ($CONFIG['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'] == '0') { $option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'][<span style="color:navy;font-weight:bolder;">0</span>] = 'checked="checked"'; $option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'][<span style="color:navy;font-weight:bolder;">1</span>] = ''; $option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'][<span style="color:navy;font-weight:bolder;">2</span>] = ''; } elseif ($CONFIG['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'] == '1') { $option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'][<span style="color:navy;font-weight:bolder;">0</span>] = ''; $option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'][<span style="color:navy;font-weight:bolder;">1</span>] = 'checked="checked"'; $option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'][<span style="color:navy;font-weight:bolder;">2</span>] = ''; } elseif ($CONFIG['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'] == '2') { $option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'][<span style="color:navy;font-weight:bolder;">0</span>] = ''; $option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'][<span style="color:navy;font-weight:bolder;">1</span>] = ''; $option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'][<span style="color:navy;font-weight:bolder;">2</span>] = 'checked="checked"'; }</pre> <a name="steps_config_rows"></a><h3>7. Output the form elements (rows)<a href="#steps_config_rows" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> In this step we finally output the actual form element - one for each plugin config option. The output basically is in HTML, with the PHP variables that we populated in the previous step shining through our HTML. That's why the entire code block that we're going to edit is using the <a href="http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc" rel="external" class="phpnet">heredoc syntax</a>, which is the recommended method as per <a href="dev_coding.htm#dev_coding_html_nesting">Coppermine coding guidelines</a>. Subsequently, all PHP variables that are meant to shine through the HTML output are being put into curly brackets.<br /> As the HTML in itself will differ substantially depending on the option type you have chosen in the <a href="#steps_config_option_type">initial step</a> of this set of instructions, here's a list of code blocks that you need to paste into <tt class="filename">c:\mysite\plugins\coffee_maker\admin.php</tt> into a new line of it's own below <pre class="cpg_code code"><!-- insert config option form code start --></pre> <div class="indent"> <a name="steps_config_rows_checkbox"></a><h4>a. Checkbox<a href="#steps_config_rows_checkbox" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h4> <pre class="code"> <tr> <td> <label for="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_donut</span>" class="clickable_option">{$lang_<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker</span>['<span style="color:red;font-weight:bolder;">donut</span>']}</label> </td> <td> <input type="checkbox" name="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_donut</span>" id="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_donut</span>" class="checkbox" value="1" {$option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_donut</span>']} /> <label for="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_donut</span>" class="clickable_option">{<span style="color:red;font-weight:bolder;">$lang_common['yes']</span>}</label> </td> </tr></pre> <a name="steps_config_rows_radio"></a><h4>b. Radio button<a href="#steps_config_rows_radio" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h4> <pre class="code"> <tr> <td style="vertical-align:top;"> {$lang_<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker</span>['<span style="color:red;font-weight:bolder;">strength</span>']} </td> <td> <input type="radio" name="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>" id="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span><span style="color:navy;font-weight:bolder;">_0</span>" class="radio" value="0" {$option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'][<span style="color:navy;font-weight:bolder;">0</span>]} /> <label for="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span><span style="color:navy;font-weight:bolder;">_0</span>" class="clickable_option">{$lang_<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker</span>['<span style="color:red;font-weight:bolder;">weak</span>']}</label><br /> <input type="radio" name="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>" id="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span><span style="color:navy;font-weight:bolder;">_1</span>" class="radio" value="1" {$option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'][<span style="color:navy;font-weight:bolder;">1</span>]} /> <label for="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span><span style="color:navy;font-weight:bolder;">_1</span>" class="clickable_option">{$lang_<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker</span>['<span style="color:red;font-weight:bolder;">normal</span>']}</label><br /> <input type="radio" name="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>" id="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span><span style="color:navy;font-weight:bolder;">_2</span>" class="radio" value="2" {$option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span>'][<span style="color:navy;font-weight:bolder;">2</span>]} /> <label for="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_strength</span><span style="color:navy;font-weight:bolder;">_2</span>" class="clickable_option">{$lang_<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker</span>['<span style="color:red;font-weight:bolder;">strong</span>']}</label> </td> </tr></pre> The example above of course will only work if you have three radio buttons; if your number of radio buttons differs, you have to add/remove lines, keeping an eye on the index numbers at the end of the strings (highlighted in <span style="color:navy;font-weight:bolder;">dark blue</span> in the example above). <a name="steps_config_rows_dropdown"></a><h4>c. Dropdown (select/option list)<a href="#steps_config_rows_dropdown" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h4> <pre class="code"> <tr> <td valign="top"> {$lang_<span style="color:orange;font-weight:bolder;">plugin_coffee_maker</span>['<span style="color:red;font-weight:bolder;">taste</span>']} </td> <td> <select name="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_taste</span>" id="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_taste</span>" class="listbox"> <option value="0" {$option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_taste</span>'][<span style="color:navy;font-weight:bolder;">0</span>]}>{$lang_<span style="color:orange;font-weight:bolder;">plugin_coffee_maker</span>['<span style="color:red;font-weight:bolder;">espresso</span>']}</option> <option value="1" {$option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_taste</span>'][<span style="color:navy;font-weight:bolder;">1</span>]}>{$lang_<span style="color:orange;font-weight:bolder;">plugin_coffee_maker</span>['<span style="color:red;font-weight:bolder;">italian</span>']}</option> <option value="2" {$option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_taste</span>'][<span style="color:navy;font-weight:bolder;">2</span>]}>{$lang_<span style="color:orange;font-weight:bolder;">plugin_coffee_maker</span>['<span style="color:red;font-weight:bolder;">latte</span>']}</option> </select> </td> </tr></pre> <a name="steps_config_rows_textinput"></a><h4>d. Text input field (one line), both for numerical input (integers) as well as any other textual input<a href="#steps_config_rows_textinput" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h4> <pre class="code"> <tr> <td valign="top"> {$lang_<span style="color:orange;font-weight:bolder;">plugin_coffee_maker</span>['<span style="color:red;font-weight:bolder;">sugar_lumps</span>']} </td> <td> <input type="text" name="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_sugar</span>" id="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_sugar</span>" class="textinput" size="2" maxlength="2" value="{$CONFIG['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_sugar</span>']}" {$option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_sugar</span>']} /> {$lang_<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker</span>['<span style="color:red;font-weight:bolder;">pieces</span>']} </td> </tr></pre> <a name="steps_config_rows_textarea"></a><h4>e. Text input field (multiple lines, <abbr title="also known as">aka</abbr> textarea)<a href="#steps_config_rows_textarea" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h4> <pre class="code"> <tr> <td valign="top"> {$lang_<span style="color:orange;font-weight:bolder;">plugin_coffee_maker</span>['<span style="color:red;font-weight:bolder;">remarks</span>']} </td> <td> <textarea name="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_remarks</span>" id="<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_remarks</span>" class="textinput" rows="7" cols="40" style="width:100%" {$option_output['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_remarks</span>']} />{$CONFIG['<span style="color:orange;font-weight:bolder;" title="Replace this with the record name you have come up with previously">plugin_coffee_maker_remarks</span>']}</textarea> </td> </tr></pre> </div> <a name="steps_config_language"></a><h3>8. Create the needed translation strings<a href="#steps_config_language" title="Link to this section"><img src="images/anchor.gif" width="15" height="9" border="0" alt="" /></a></h3> Basically, we're done already, except for the language strings that we had to come up with in the form elements: our config option needed a name and maybe some explanatory text, and the option labels (if applicable) required additional strings. Those strings need to be defined in the language file: our plugin template already contains an English language file that we need to populate no matter what, that's why you need to edit that file (<tt class="filename">c:\mysite\plugins\coffee_maker\lang\english.php</tt>) with your plain text editor as well. The structure of the language files is pretty straightforward: you just define array records as suggested in the <a href="translation.htm#translation_step_by_step">translation guide</a> for "regular" Coppermine language files that applies for plugin language files just as well. Just keep in mind that apostrophes (single quotes) in your language strings need to be escaped with a leading backslash.<br /> For the examples given above, the following translation strings would have to be added to the language file: <pre class="code">$lang_plugin_coffee_maker['donut'] = 'Donut'; $lang_plugin_coffee_maker['strength'] = 'Strength'; $lang_plugin_coffee_maker['weak'] = 'weak'; $lang_plugin_coffee_maker['normal'] = 'normal'; $lang_plugin_coffee_maker['strong'] = 'strong'; $lang_plugin_coffee_maker['taste'] = 'Taste'; $lang_plugin_coffee_maker['espresso'] = 'Espresso'; $lang_plugin_coffee_maker['italian'] = 'Italian'; $lang_plugin_coffee_maker['latte'] = 'Latte'; $lang_plugin_coffee_maker['sugar_lumps'] = 'Sugar lumps'; $lang_plugin_coffee_maker['pieces'] = 'pieces'; $lang_plugin_coffee_maker['remarks'] = 'Remarks';</pre> </div> This is all that needs to be done to add config options to your custom plugin. Remember though that adding the option records alone will of course not do anything yet in terms of functionality of your plugin - you need to come up with code as well that is making use of your plugin's config options. When using your config options from within functions, don't forget to set the scope of the variable <tt class="code">$CONFIG</tt> using the keyword <a href="http://www.php.net/manual/en/language.variables.scope.php" rel="external" class="phpnet">global</a>.<br /> Keep in mind as well (before testing your plugin's config options) that you need to uninstall and re-install it, as the database records are being created during plugin install only. </div> <div id="doc_footer"> <div class="doc_info_wrapper"> <span id="doc_last_changed">$LastChangedDate: 2011-01-02 20:44:22 +0100 (So, 02 Jan 2011) $</span> <span id="doc_revision">$Revision: 8154 $</span> </div> </div> </body> </html>