Joomla! 1.0 component tutorial - part 2: back-end

Now the display file - admin.jportfsimple.html.php - which displays the information provided by the "logic" file, earlier, or shows forms and input fields to enter new information.

All backed functions are members of HTML_jportfsimple class:

admin.jportfsimple.html.php
  1. // no direct access
  2. defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
  3.  
  4.  
  5. class HTML_jportfsimple{

Configuration listing function is an example of using tabs, and also editor:

admin.jportfsimple.html.php
  1. /**
  2. * Configuration listing
  3. */
  4. function Conf_list( $option )
  5. {
  6.   global $jpConf;
  7. ?>
  8.  
  9. <script language="javascript" type="text/javascript">
  10.         function submitbutton(pressbutton) {
  11.                 <?php getEditorContents( 'editor', 'description' ); ?>
  12.                 submitform( pressbutton );
  13.         }
  14. </script>
  15.  
  16. <script language="Javascript" src="js/dhtml.js"></script>
  17.  
  18. <table class="adminheading">
  19.     <tr>
  20.       <th><?php echo _COM_JP_CONFIG_INFO ?></th>
  21.     </tr>
  22. </table>
  23.  
  24. <table cellpadding="4" cellspacing="0" border="0" width="100%">
  25. <tr>
  26. <td width="5%" class="tabpadding"> </td>
  27. <td id="tab1" class="offtab" onClick="dhtml.cycleTab(this.id)">Settings</td>
  28. <td id="tab2" class="offtab" onClick="dhtml.cycleTab(this.id)">CSS</td>
  29. <td width="5%" class="tabpadding"> </td>
  30. </tr>
  31. </table>
  32.  
  33. <form action="index2.php" method="post" name="adminForm">
  34. <div id="page1" class="pagetext">
  35.  
  36. <table cellpadding="4" cellspacing="0" border="0" width="90%" class="adminlist">
  37. <tr>
  38.   <th class="title" width="10%"><?php echo _COM_JP_CONFIG_PARAMETER ?></th>
  39.   <th class="title" width="20%"><?php echo _COM_JP_CONFIG_VALUE ?></th>
  40.   <th class="title"><?php echo _COM_JP_CONFIG_DESCR ?></th>
  41. </tr>
  42.  
  43. <tr>
  44.   <td><?php echo _COM_JP_CONFIG_BASEPATH ?>    </td>
  45.   <td><input size="30" name="base_path" value="<?php echo $jpConf->base_path; ?>"> </td>
  46.   <td><?php echo _COM_JP_CONFIG_BASEPATH_DESCR ?> </td>
  47. </tr>
  48.  
  49. <tr>
  50.   <td><?php echo _COM_JP_CONFIG_TITLE ?>    </td>
  51.   <td><input size="30" name="title" value="<?php echo $jpConf->title; ?>"> </td>
  52.   <td><?php echo _COM_JP_CONFIG_TITLE_DESCR ?> </td>
  53. </tr>
  54.  
  55. <tr>
  56.   <td valign="top" ><?php echo _COM_JP_CONFIG_FRONT_DESCR ?>    </td>
  57.   <td  align="center" colspan="2">
  58.   <?php
  59.     editorArea( 'editor'$jpConf->description , 'description', '600', '220', '60', '40' ) ;
  60.   ?>
  61.   </td>
  62. </tr>
  63. </table>
  64. </div>
  65.  
  66. <div id="page2" class="pagetext">
  67.  
  68. <table cellpadding="4" cellspacing="0" border="0" width="90%" class="adminlist">
  69.  
  70. <tr>
  71.   <th class="title" width="10%"><?php echo _COM_JP_CONFIG_PARAMETER ?></th>
  72.   <th class="title" width="20%"><?php echo _COM_JP_CONFIG_VALUE ?></th>
  73.   <th class="title"><?php echo _COM_JP_CONFIG_DESCR ?></th>
  74. </tr>
  75.  
  76. <tr>
  77.   <td valign="top" ><?php echo _COM_JP_CONFIG_CSS ?>    </td>
  78.   <td><input size="30" name="css_file" value="<?php echo $jpConf->css_file; ?>"> </td>
  79.   <td valign="top" ><?php echo _COM_JP_CONFIG_CSS_DESCR ?>    </td>
  80. </tr>
  81. </table>
  82. </div> 
  83.  
  84. <input type="hidden" name="option" value="<?php echo $option; ?>" />
  85. <input type="hidden" name="task" value="" />
  86. <?php if ($jpConf->id) { ?>
  87. <input type="hidden" name="id" value=<?php echo $jpConf->id ?> />
  88. <?php } ?>
  89. <input type="hidden" name="act" value="configure" />
  90. </form>
  91.  
  92. <script language="javascript" type="text/javascript">dhtml.cycleTab('tab1');</script>
  93.  
  94. <?php
  95. }

Lines 38 to 43 - are required for using WYSIWYG editor in a form (actually to get back the content of an editor). Editor is loaded in line 88. Notice the name of the editor field: 'editor' - if you'd like to use more than one editor, their names should be unique.

45 - this is needed for tabs. Their displayed names are defined in lines 56, 57, first open tab is defined in line 121, and then each tab content is displayed within a div. So here:

tab1 - name: Settings, div id=page1 (line 63, 93)

tab2 - name: CSS,  div id=page2 (line 95, 111)

As you see, each input field must have it's name, which must be the same as defined in class file, depending on object which is edited.

The "hidden" fields (lines 113 to 118) are used to pass other variables, like $option or $act, so the backend "knows" where to go after you press "Save". Variable $task is empty initially - it's value is assigned when actual button in pressed. Variable $id is needed so the right record is saved. In case of configuration there is always only 1 record.

Categories listing function:

admin.jportfsimple.html.php
  1. /**
  2. * Category listing
  3. */
  4. function Cat_list( $option, &$rows, &$pageNav )
  5. {
  6. ?>
  7.  
  8. <form action="index2.php" method="post" name="adminForm">
  9.  
  10. <table class="adminheading">
  11.     <tr>
  12.       <th><?php echo _COM_JP_ALBUMS_INFO ?></th>
  13.     </tr>
  14. </table>
  15.  
  16. <table cellpadding="4" cellspacing="0" border="0" width="100%" class="adminlist">
  17. <tr>
  18.   <th width="20"><input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count($rows); ?>);" /></th>
  19.   <th class="title" width="20%"><?php echo _COM_JP_ALBUM_NAME ?></th>
  20.   <th class="title"><?php echo _COM_JP_ALBUM_PATH ?></th>
  21.   <th class="title"><?php echo _COM_JP_ALBUM_INFO ?></th>
  22.   <th width="5%"colspan="2" align="center"><?php echo _COM_JP_ORDER; ?></th>
  23.   <th width="7%"></th>
  24.   <th width="7%"><?php echo _COM_JP_CONFIG_PUBLISHED; ?> </th>
  25. </tr>
  26.  
  27. <?php
  28. if (count($rows)<1) echo '<tr><td colspan="8" ><center><b>'._COM_JP_NO_CAT.'</b></center></td></tr>';
  29.  
  30.   $k = 0;
  31.   for ($i=0, $n=count( $rows ); $i < $n; $i++)
  32.   {
  33.   $row = &$rows[$i];
  34.  
  35. ?>
  36. <tr class="<?php echo "row$k"; ?>">
  37.   <td><input type="checkbox" id="cb<?php echo $i;?>" name="cid[]" value="<?php echo $row->id; ?>" onclick="isChecked(this.checked);" /></td>
  38.   <td><a href="#edit" onclick="hideMainMenu();return listItemTask('cb<?php echo $i;?>','edit')"><?php echo $row->cat_name; ?></a></td>
  39.   <td><?php echo $row->cat_path; ?></td>
  40.   <td><?php echo substr($row->cat_info,0,30); ?></td>
  41.   <td>
  42.   <?php echo $pageNav->orderUpIcon( $i, 1 ); ?>
  43.   </td>
  44.   <td>
  45.   <?php echo $pageNav->orderDownIcon( $i, $n, 1 ); ?>
  46.   </td>
  47.   <td>
  48.   </td>
  49.   <td align="center">
  50. <?php
  51.   if ($row->published == "1") {
  52.   echo "<a href=\"javascript: void(0);\" onClick=\"return listItemTask('cb$i','unpublish')\"><img src=\"images/publish_g.png\" border=\"0\" /></a>";
  53.   } else {
  54.   echo "<a href=\"javascript: void(0);\" onClick=\"return listItemTask('cb$i','publish')\"><img src=\"images/publish_x.png\" border=\"0\" /></a>";
  55.   }
  56. ?>
  57.   </td>
  58. <?php $k = 1 - $k; ?>
  59. </tr>
  60.  
  61. <?php
  62.   }
  63. ?>
  64.  
  65. </table>
  66. <?php echo $pageNav->getListFooter(); ?>
  67.  
  68. <input type="hidden" name="option" value="<?php echo $option; ?>" />
  69. <input type="hidden" name="task" value="" />
  70. <input type="hidden" name="boxchecked" value="0" />
  71. <input type="hidden" name="hidemainmenu" value="0" />
  72. <input type="hidden" name="act" value="categories" />
  73. </form>
  74.  
  75. <?php
  76. }

Here or in any similar listing function, few blocks are used:

lines 141 to 150 - start of table, and column headers

153 - if no category defined yet, display warning
156 - loop through all categories
162 - checkbox for selecting categories
163 - displays category name with Javascript returning 'edit' value for $task variable
167, 170 - displays reordering icons
176 to 180 - displays 'published' or 'unpublished' icon
191 - displays select list - how many categories per page to display

Next function - category editing - is similar to configuration editing. Additionally it has Javascript doing basic field validation. It displays popup warning if category name or folder are not entered.

admin.jportfsimple.html.php
  1. <script language="javascript" type="text/javascript">
  2.         function submitbutton(pressbutton) {
  3.         var form = document.adminForm;
  4.       if (pressbutton == 'cancel') {
  5.         submitform( pressbutton );
  6.         return;
  7.       }
  8.  
  9.       // do fields validation
  10.       if (form.cat_name.value == ''){
  11.         alert( "Category must have a name" );
  12.       } else if (form.cat_path.value == ''){
  13.         alert( "You must select a category folder" );
  14.       } else {
  15.         <?php getEditorContents( 'editor', 'description' ); ?>
  16.         submitform( pressbutton );
  17.       }
  18.         }
  19. </script>


Project listing and project editing functions are similar to the above ones.

Last function is 'Info' which displays information about the component. It shows logo, short description and version as defined in language file constants (_COM_JP_DESC, _COM_JP_VER1) and then it includes HTML file from help folder.

admin.jportfsimple.html.php
  1. if (file_exists( $mosConfig_absolute_path.'/administrator/components/com_jportfsimple/help/'. $mosConfig_lang.'.html'))
  2.     include_once( $mosConfig_absolute_path.'/administrator/components/com_jportfsimple/help/'. $mosConfig_lang.'.html');
  3.   else
  4.   if (file_exists( $mosConfig_absolute_path.'/administrator/components/com_jportfsimple/help/english.html'))
  5.     include_once( $mosConfig_absolute_path.'/administrator/components/com_jportfsimple/help/english.html');

If information in other language is not available, it will show english.html by default. It could be done differently - whole information could be also entered in one constant in language file, but I found it easier to update this way.