How complicated you want it?

A general technical discussion area for patTemplate.
Locked
alwarren
Joomla! Guru
Joomla! Guru
Posts: 527
Joined: Fri Aug 19, 2005 9:27 am

How complicated you want it?

Post by alwarren » Sat Oct 29, 2005 5:05 am

Here's a tickler. I'm working on a component that displays a table. Users can submit entries similar to how they can for content. Imbedded in the last column of the table is my input form. There are various options that can be set - form public or private, list public or private, email public or private, etc. Against all intuition, I decided to see if I could control the entire output with patTemplat sub conditions. I managed to make it work but the template sure was a mess. So what I did was break the templating down into two portions - a logic template file and an output template file. The logic has no html in it - only nested templates, calls to external templates, and all the associated sub condition templates. Something else I considered was how to handle translation. Translation in the J! version of pat requires a global $_LANG object. Personally, I like the way pat handled it but that's what we have to work with. I have a language object in my component. Initially I added that object to my output templates to handle translation. But as I begin breaking the html down into various sub-templates, it occured to me to be lazy and dispense with a language object alltogether. Why? Well, the html contains verbage. Since I can load whatever template file I want, why not use the J! language variable and name my templates accordingly. So what I have now is two template files - logic.tmpl.html and english.tmpl.html. All one has to do is create a copy of english.tmpl.html, translate it, and name it with the appropriate language name. Like I said, it was a bit on the lazy side but what the heck - it works.

The main difference I found in letting the template handle logic is how to set it all up. First, you have to massage your condition variables and objects to prepare them to work with the patTemplate engine. You have to think simple. You have very limited options. But there are enough to do pretty much what you want. One example is the template type "simplecondition". It basically checks to see if a variable exists. So to prepare the template, you must unset variables that would normally be null or zero. The next option is to us a normal condition which amounts to a switch case with a smattering of pat system variables available. There are a few others but I haven't tried them all yet. Another thing you must consider is variable scope. Scope works just like it does in Php. A variable is only seen by it's local container. So if, for example, you have a sub-condition template within template main and you need access to a variable in mains scope, you must use "varscope=main". You could just as easy add the variable to the sub-condition template but often you'll want access to  variables and objects from within various sub templates. I found it easier to add most everything to a main template and use varscope. The one exception is if you add an array to a template. When you do that, your template will repeat for each key/value of the array. But of course that's exactly what you want to do when you're working with a database object list.

Back to the subject of the post. As a tickler, let me attach a screen shot of the output and then show you the php and template files. It get's pretty crazy but hey, it works.

Here is the php:

Code: Select all

	function listEntries( $rows, $ecTrader ) {
		HTML_ectrader::initEctraderObj( &$ecTrader );
		HTML_ectrader::initRows( &$rows, $ecTrader );
		$tmpl =& HTML_ectrader::createTemplate( $ecTrader->_option );
		$file = $ecTrader->_lang . "_templates.tmpl.html";
		$tmpl->readTemplatesFromInput( $file );
		$file = $ecTrader->_lang . "_logic.tmpl.html";
		$tmpl->readTemplatesFromInput( $file );

		$tmpl->addGlobalVar( 'count', count($rows));
		$tmpl->addGlobalVar( 'task', $ecTrader->_task);
		$tmpl->addGlobalVar( 'nexttask', $ecTrader->_nextTask);
		$tmpl->addGlobalVar( 'Itemid', $ecTrader->_Itemid);
		$tmpl->addGlobalVar( 'uid', $ecTrader->_uid);
		$tmpl->addGlobalVar( 'id', $ecTrader->_editrow->id);
		$tmpl->addGlobalVar( 'limit', $ecTrader->_limit);

		$tmpl->addVar( 'main', 'uid', $ecTrader->_uid);
		$tmpl->addVar( 'main', 'viewlist', $ecTrader->_allowListView);
		$tmpl->addVar( 'main', 'viewform', $ecTrader->_allowFormView);
		$tmpl->addVar( 'main', 'showeditlink', $ecTrader->_showEditLink);
		$tmpl->addVar( 'main', 'showemail', $ecTrader->_showEmail);
		$tmpl->addVar( 'main', 'showdeletelink', $ecTrader->_showDeleteLink);
		$tmpl->addVar( 'main', 'messagesallowpublic', $ecTrader->_messagesAllowPublic);
		$tmpl->addVar( 'main', 'select_limitbox', $ecTrader->_editlists['limitBox'] );
		$tmpl->addVar( 'main', 'select_order', $ecTrader->_editlists['order'] );
		$tmpl->addVar( 'main', 'select_pagenav', $ecTrader->_editlists['pagenav'] );
		$tmpl->addVar( 'main', 'select_pagecounter', $ecTrader->_editlists['pagecounter'] );

		$tmpl->addObject( 'main', $ecTrader->_translate, 'translate_' );
		$tmpl->addObject( 'row', $rows, 'row_' );

		$tmpl->addObject( 'table', $ecTrader->_editrow, 'editrow_' );
		$tmpl->addVar( 'table', 'select_trans', $ecTrader->_editlists['transactions'] );
		$tmpl->addVar( 'table', 'select_cur', $ecTrader->_editlists['currency'] );
		$tmpl->addVar( 'table', 'select_showemail', $ecTrader->_editlists['showemail'] );
		$tmpl->addVar( 'table', 'select_email', $ecTrader->_editlists['email'] );

		$tmpl->displayParsedTemplate( 'main' );
		return;
	} // end function ectrader
Here is the template logic (logic.tmpl.php):

Code: Select all

<mos:tmpl name="main">
<mos:tmpl name="jscondition" type="simplecondition" requiredvars="viewform" varscope="main">
   <mos:Call template="joomla_js" />
   <mos:Call template="javascript" />
</mos:tmpl>
<mos:Call template="formstart" />
<mos:Call template="component_heading" />
<mos:Call template="tablestart"/>
<mos:tmpl name="showmessageshead" type="simplecondition" requiredvars="messagesallowpublic" varscope="main">
   <mos:Call template="th_messages" />
</mos:tmpl>
<mos:tmpl name="formhead" type="simplecondition" requiredvars="viewform" varscope="main">
   <mos:Call template="th_form" />
</mos:tmpl>
<mos:Call template="tr_end" />
<mos:tmpl name="row" varscope="main">
   <mos:Call template="rows_start" />
   <mos:Call template="rows" />
   <mos:tmpl name="messagesallowpublic" type="simplecondition" requiredvars="main.messagesallowpublic" varscope="row">
      <mos:Call template="td_messages" />
      <mos:tmpl name="emailcond" type="condition" conditionvar="row_showemail" varscope="row">
         <mos:sub condition="__default">
            <mos:Call template="link_email" />
         </mos:sub>
         <mos:sub condition="__empty">
            <mos:Call template="nolink_email" />
         </mos:sub>
      </mos:tmpl>
      <mos:tmpl name="allowedit" type="simplecondition" requiredvars="row_allowedit" varscope="row">
         <mos:tmpl name="showeditlink" type="simplecondition" requiredvars="showeditlink" varscope="row">
            <mos:Call template="link_edit" />
         </mos:tmpl>
         <mos:tmpl name="showdeletelink" type="simplecondition" requiredvars="showdeletelink" varscope="row">
            <mos:Call template="link_delete" />
         </mos:tmpl>
      </mos:tmpl>
      <mos:Call template="messages" />
      <mos:Call template="td_end" />
   </mos:tmpl>
   <mos:tmpl name="tablecondition" type="simplecondition" requiredvars="viewform" varscope="main">
      <mos:tmpl name="table" type="condition" conditionvar="row.row_created">
		<mos:sub condition="__single">
            <mos:Call template="editform_start" />
            <mos:tmpl name="edit" type="condition" conditionvar="editrow_id" varscope="table">
               <mos:sub condition="__default">
                  <mos:Call template="editform_top" />
               </mos:sub>
               <mos:sub condition="0" />
            </mos:tmpl>
            <mos:Call template="editform_body" />
            <mos:tmpl name="uid_emailcondition" type="condition" conditionvar="main.uid" varscope="table">
               <mos:sub condition="__empty">
                  <mos:Call template="editform_email" />
               </mos:sub>
            </mos:tmpl>
                  <mos:tmpl name="taskcondition" type="condition" conditionvar="task" varscope="table" useglobals="yes">
                     <mos:sub condition="edit">
                        <mos:tmpl name="uidcondition" type="condition" conditionvar="editrow_uid" varscope="table" useglobals="yes">
                           <mos:sub condition="0">
                              <mos:Call template="editform_email" />
                           </mos:sub>
                        </mos:tmpl>               
                     </mos:sub>
                  </mos:tmpl>               
            <mos:Call template="editform_showemail" />
            <mos:tmpl name="guest_noticecondition" type="condition" conditionvar="main.uid" varscope="table">
              <mos:sub condition="__empty">
                  <mos:Call template="guest_notice" />
              </mos:sub>
            </mos:tmpl>
            <mos:Call template="editform_end" />
		</mos:sub>
         <mos:sub condition="__first">
            <mos:Call template="editform_start" />
            <mos:tmpl name="edit_first" type="condition" conditionvar="editrow_id" varscope="table">
               <mos:sub condition="__default">
                  <mos:Call template="editform_top" />
               </mos:sub>
               <mos:sub condition="0" />
            </mos:tmpl>
            <mos:Call template="editform_body" />
            <mos:tmpl name="uid_emailcondition_first" type="condition" conditionvar="main.uid" varscope="table">
               <mos:sub condition="__empty">
                  <mos:Call template="editform_email" />
               </mos:sub>
            </mos:tmpl>
                  <mos:tmpl name="taskcondition_first" type="condition" conditionvar="task" varscope="table" useglobals="yes">
                     <mos:sub condition="edit">
                        <mos:tmpl name="uidcondition_first" type="condition" conditionvar="editrow_uid" varscope="table" useglobals="yes">
                           <mos:sub condition="0">
                              <mos:Call template="editform_email" />
                           </mos:sub>
                        </mos:tmpl>               
                     </mos:sub>
                  </mos:tmpl>               
            <mos:Call template="editform_showemail" />
            <mos:tmpl name="guest_noticecondition_first" type="condition" conditionvar="main.uid" varscope="table">
              <mos:sub condition="__empty">
                  <mos:Call template="guest_notice" />
              </mos:sub>
            </mos:tmpl>
            <mos:Call template="editform_end" />
         </mos:sub>
      </mos:tmpl>
   </mos:tmpl>
   <mos:Call template="tr_end" />
</mos:tmpl>
<mos:Call template="formend" />
<mos:Call template="pagenav" />
</mos:tmpl>
And here are the output templates (english.tmpl.html):

Code: Select all

<mos:tmpl name="main">
<mos:tmpl name="jsinclude" type="condition" conditionvar="uid" varscope="main">
   <mos:sub condition="0">
		<script language="JavaScript" src="{SITEURL}/includes/js/joomla.javascript.js" type="text/javascript"></script>
   </mos:sub>
</mos:tmpl>
<script language="javascript" type="text/javascript">
   // onunload = WarnUser;
   function submitbutton(pressbutton, id) {
      var form = document.adminForm;
      // do field validation
      if (pressbutton == 'cancel') {
         submitform( pressbutton );
         return;
      } else {
         if (pressbutton == 'delete')
            if ( confirm("Are you sure you want to delete this record?") ) {
               form.task.value = 'delete';
               if (id) form.id.value = id;
               submitform( pressbutton );
		       return;
            } else {
			   return;
         }
      }
      if ( (form.transaction.value == '') || (form.transaction.value == '0') ) {
         alert('Please select a transaction type');
         return;
      } else if ( (form.currency.value == '') || (form.currency.value == '0') ) {
         alert('Please select an eCurrency');
         return;
      } else if ( (form.amount.value == '') || (form.amount.value == '0') ) {
         alert('Please select an amount');
         return;
      } else {
	     submitform( pressbutton );
	  }
   }
//   document.adminForm.submit();
</script>
<form method="post" action="index.php" name="adminForm">
   <input type ="hidden" name="option" value="{OPTION}">
   <input type ="hidden" name="task" value="{TASK}">
   <input type ="hidden" name="Itemid" value="{ITEMID}">
   <input type ="hidden" name="modified_by" value="{UID}">
   <input type ="hidden" name="uid" value="{UID}">
   <input type ="hidden" name="id" value="{ID}">
<table class="contentpane" cellspacing="2px" cellpadding="3px" style="border: 1px solid;">
  <tr style="color: #000000; font-size: 1.1em; text-align: center; border: 1px solid #ffffff; background-color: #cccccc"class="contentheading">
    <th>Time Added</th>
    <th>Buy/Sell</th>
    <th>Ecurrency</th>
    <th>Amount</th>
    <th>Rate</th>
   <mos:tmpl name="showmessageshead" type="simplecondition" requiredvars="messagesallowpublic" varscope="main">
    <th>Buyer/Seller Messages</th>
   </mos:tmpl>
   <mos:tmpl name="tablehead" type="simplecondition" requiredvars="viewform" varscope="main">
    <th>Add Buy Or Sell eCurrency</th>
   </mos:tmpl>
  </tr>
   <mos:tmpl name="row" varscope="main">
  <tr style="text-align: center; vertical-align: middle; border: 1px solid #ffffff; background-color: #f0f0f0">
    <td nowrap>{ROW_CREATED}</td>
    <td>{ROW_TRANSACTION}</td>
    <td>{ROW_CURRENCY}</td>
    <td>{ROW_AMOUNT}</td>
    <td>{ROW_RATE}</td>
   <mos:tmpl name="messagesallowpublic" type="simplecondition" requiredvars="main.messagesallowpublic" varscope="row">
    <td style="text-align: left">
	<mos:tmpl name="emailcond" type="condition" conditionvar="row.row_showemail" varscope="row">
	   <mos:sub condition="__default">
	<a href="mailto:{ROW_EMAIL}" title="Email {ROW_EMAIL}">{ROW_USERNAME}</a>
	   </mos:sub>
	   <mos:sub condition="__empty">
	<b>{ROW_USERNAME}</b>
	   </mos:sub>
	</mos:tmpl>
      <mos:tmpl name="showimages" type="simplecondition" requiredvars="row_image" varscope="row">
      <a href="{ROW_EDITLINK}" title="Edit Record"><img src="{ROW_IMAGE}" width=14 height =14 alt="Edit Record" style="border:0"/></a> 
	  <a href="javascript:submitbutton('delete', {ROW_ID});" title="Delete record"><img src="{ROW_IMAGEDELETE}" width=12 height =12 alt="Delete Record" style="border:0"/></a>
      </mos:tmpl>
   <br />{ROW_MESSAGE}
   </td>
   </mos:tmpl>
      <mos:tmpl name="tablecondition" type="simplecondition" requiredvars="viewform" varscope="main">
      <mos:tmpl name="table" type="condition" conditionvar="row.row_created">
         <mos:sub condition="__first">
      <td rowspan="{COUNT}">
         <div style="text-align: left">
<table style="border: solid 1px #000000; float: right">
         <mos:tmpl name="edit" type="condition" conditionvar="editrow_id" varscope="table">
            <mos:sub condition="__default">
   <tr>
      <td>Record Id:
      </td>
      <td>{EDITROW_ID}  <a href="javascript:submitbutton('delete');" title="Delete record">[Delete]</a>  <a href="javascript:submitbutton('cancel');" title="Cancel Edit">[Cancel]</a>
	     <input type ="hidden" name="uid" value="{EDITROW_UID}">
	     <input type ="hidden" name="created" value="{EDITROW_CREATED}">
	     <input type ="hidden" name="published" value="{EDITROW_PUBLISHED}">
	     <input type ="hidden" name="checkedout" value="{EDITROW_CHECKEDOUT}">
	     <input type ="hidden" name="access" value="{EDITROW_ACCESS}">
      </td>
   </tr>
   <tr>
      <td>Username:
      </td>
      <td>{EDITROW_USERNAME}
      </td>
   </tr>
            </mos:sub>
            <mos:sub condition="0" />
         </mos:tmpl>
   <tr>
       <td>Buy/Sell:
       </td>
       <td>{SELECT_TRANS}
       </td>
    </tr>
   <tr>
      <td>eCurrency:
      </td>
      <td>{SELECT_CUR}
      </td>
   </tr>
   <tr>
      <td>Amount:
      </td>
      <td><input type="text" name="amount" class="inputbox" size="4" value="{EDITROW_AMOUNT}" />
      </td>
   </tr>
   <tr>
      <td>Rate:
      </td>
      <td><input type="text" name="rate" class="inputbox" size="4" value="{EDITROW_RATE}" />
      </td>
   </tr>
   <tr>
      <td  colspan="2">Additional Message:<br />
      <textarea name="message" class="inputbox" cols="30" rows="7">{EDITROW_MESSAGE}</textarea><br />
	  Show email: {SELECT_SHOWEMAIL}
      </td>
   </tr>
   <tr>
      <td  colspan="2">
        <div align="center">
           <input type="button" value="Submit" name="savebutton" onclick="submitbutton('{TASK}')">  
           <input type="reset" value="Reset" name="resetbutton">
        </div>
      </td>
   </tr>
</table>
        </div>
     </td>
         </mos:sub>
      </mos:tmpl>
      </mos:tmpl>
  </tr>
   </mos:tmpl>
</table>
</form>
</mos:tmpl>
How efficient is it? Probably not very. Is the logic template easy to debug? Not very, lol. Is the html template easy to edit? Very. It is also very easy to read and/or translate. Now remember, I was really just trying to push the envelope as far as how much "coding" I could do with patTemplates. It's fairly powerful. I'm looking forward to digging into it more to see just what we can do with it. I'll try to come up with some better/easier examples in the near future. I just wanted to throw this out there as an example of how crazy you can get with pat.
You do not have the required permissions to view the files attached to this post.
Al Warren
This ain't my first rodeo. Red Foreman says it best.
CQDX de WR5AW

Locked

Return to “patTemplate”