• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Issues with Error Pages

#1
Exclamation 
I was trying to customize the error pages for my application, the issue im having right now I believe is related to the PHP and MySQL error templates.

When an error is encountered, for example, a PHP error, it will display the entire content of views/errors/html/error_php.php, within the partly generated page that the error occurred in.

Is there a way to have it ONLY show the content of views/errors/html/error_php.php ?
Reply

#2
I know this isn't the answer you're looking for, but the answer is, more or less, to not have code in your view(s) which is likely to generate an error. PHP isn't going to let you start output, then go back and replace the previous output when it encounters an error during the output process. However, if you encounter an error before you start output, you're probably going to handle the error a little differently, anyway.

You might be able to put some JavaScript in your error view to redirect the user to an error page, but that's still dependent on the user having JavaScript enabled (a PHP redirect will just cause another error, since the headers have already been sent).
Reply

#3
(09-22-2015, 08:48 AM)mwhitney Wrote: I know this isn't the answer you're looking for, but the answer is, more or less, to not have code in your view(s) which is likely to generate an error. PHP isn't going to let you start output, then go back and replace the previous output when it encounters an error during the output process. However, if you encounter an error before you start output, you're probably going to handle the error a little differently, anyway.

You might be able to put some JavaScript in your error view to redirect the user to an error page, but that's still dependent on the user having JavaScript enabled (a PHP redirect will just cause another error, since the headers have already been sent).

I see, since the error is in the PHP of the view, then its going to get the view content and the error content mixed together.

Thats a good enough answer, thank you!.

The icons on my application/website are able to be changed by changing the JSON file, and I have a helper function that will output it, for example..
PHP Code:
<?=icon('desktop','lg')?>
would insert the code for a large desktop icon. The error was due to some undefined variables, so ill just add a @ to the icon function to hide them, unless you know of a better way to change the icons in the view without a function in it?
Reply

#4
Set default values for the variables and/or the inputs on the helper function and make the function itself as safe as possible. In cases where I need to avoid errors, I use ternary operators and isset()/empty() calls in a code block at the top of the view to set defaults for all of the variables I'm going to use in that view. For example:

PHP Code:
$something = isset($something) ? $something 'safe default value'

Handling the inputs on the helper function would really be dependent on the range of valid values and whether it would be more appropriate to make some assumptions when the input is invalid (or missing) or just do nothing. In general, if I'm creating a function to be used by a view to generate HTML, I tend to prefer returning an empty string or an empty element, or throw an Exception so the view can decide how to handle the error.

If I'm having trouble tracking down an instance of a variable not being set, I might even use a helper function to log any information I think might be useful.
Reply

#5
(09-23-2015, 07:57 AM)mwhitney Wrote: Set default values for the variables and/or the inputs on the helper function and make the function itself as safe as possible. In cases where I need to avoid errors, I use ternary operators and isset()/empty() calls in a code block at the top of the view to set defaults for all of the variables I'm going to use in that view. For example:




PHP Code:
$something = isset($something) ? $something 'safe default value'

Handling the inputs on the helper function would really be dependent on the range of valid values and whether it would be more appropriate to make some assumptions when the input is invalid (or missing) or just do nothing. In general, if I'm creating a function to be used by a view to generate HTML, I tend to prefer returning an empty string or an empty element, or throw an Exception so the view can decide how to handle the error.

If I'm having trouble tracking down an instance of a variable not being set, I might even use a helper function to log any information I think might be useful.


What I usually do is basically the same, You can shorten up that ternary operator by not adding the first $something, I believe its in PHP >= 5.3

And since I'm requiring my app to have PHP >= 5.4, I can use the PHP open tags, without having to worry about if its enabled or not.

So I just do...
PHP Code:
<input value="<?=(@$something ?: 'safe default value')?>"/> 


I do however, have a very very very nasty view file, which has WAY more PHP than it should. one reason is that it parses a mustache template (I chose mustache because I needed a template that could be parsed in PHP AND jQuery). 

The template is actually for a <tr> in a table, which has cells with very dynamic content. And since the template itself doesn't support conditional statements (or ANY logic at all... Angry Confused )  my view file has a foreach loop, with a lot of logic inside of it, to set the values of the view file.. The code is below. If you think you can help me out with simplifying the view, then ill sell you my sole Big Grin


View File (Just the <table> part) [External Link]:
PHP Code:
<table id="data-table" class="table table-bordered <?=TABLE_STYLE_CLASSES?>">
 
   <thead>
 
   <tr>
 
       <th></th>
 
       <th class="ttip width-10 p-9" title="Sort the field by dragging the rows using this row as the handle">
 
       </th>
 
       <th title="Delete this row" class="width-5 ttip p-10">
 
           <class="fa fa-lg fa-trash-o"></i>
 
       </th>
 
       <th title="Field Visibility, unchecked will restrict this field from being visible on search forms and search results" class="width-5 ttip p-10">
 
           <class="fa fa-lg fa-eye"></i>
 
       </th>
 
       <th title="Primary value for partition <i>(Not all types can be a primary value)</i>. Click on the text in the header to unselect the primary field" class="width-5 ttip p-10">
 
           <span class="cancel-primary"><class="fa fa-lg fa-key"></i></span>
 
       </th>
 
       <th title="Name for the field <i>(Unique, per partition)</i>" class="width-20-pc ttip">
 
           Name
        
</th>
 
       <th title="Description for field <i>(Recommended, but not required)</i>" class="width-10-pc ttip">
 
           Description
        
</th>
 
       <th title="Placeholder shown inside input" class="width-5-pc ttip">
 
           Placeholder
        
</th>
 
       <th title="Specify if field is required for assets" class="ttip width-100">
 
           Req
        
</th>
 
       <th title="Specify if field value needs to be unique <i>(As in unique per partition)</i>" class="ttip width-100">
 
           Uniq
        
</th>
 
       <th title="Specify if field values must match this regex<br><strong>NOTE:</strong> ONLY use this feature if you are absolutely positive that you know what you're doing, as an improperly formed regex string will hinder the field" class="width-20-pc ttip">
 
           Regex
        
</th>
 
       <th title="Minimum length for field value, using this for multi-selects will set the minimum number of options required to be selected" class="width-5-pc ttip">
 
           Min
        
</th>
 
       <th title="Maximum length for field value, using this for multi-selects will set the maximum number of options required to be selected" class="width-5-pc ttip">
 
           Max
        
</th>
 
       <th title="Type of field value" class="ttip width-100">
 
           Type
        
</th>
 
       <th title="Options and default values for field.<br><strong>NOTE:</strong> Required for <strong>Select</strong>, <strong>Multiselect</strong> and <strong>Dependent</strong> field types" class="width-25-pc ttip">
 
           Options and Default Values
        
</th>
 
   </tr>
 
   </thead>
 
   <tbody>
 
   <?php
    
// Add all existing fields, if EDITING partition
 
   if(isset($partition->fields))
 
   {
 
       $counter 0;

 
       foreach$partition->fields as $k => $p )
 
       {
 
           $row_conf = array(
 
               "counter"           => $counter,
 
               "values"            => [],
 
               "type_{$p->type}  => $p->type,
 
               "current_type"      => $p->type,
 
               "column_name"       => $p->column_name,
 
               "order"             => $p->order
            
);

 
           // NOTE: Using mustache template engine, these below values cant be used in conditional
 
           // statements, so even if they are set to FALSE, it will be interpreted as TRUE since
 
           // it exists. So do NOT convert these to ternary operators, or try to simplify in any way
 
           if( @$p->primary == )
 
               $row_conf['primary'] = TRUE;

 
           if( @$p->unique == )
 
               $row_conf['unique'] = TRUE;

 
           if( @$p->visible == )
 
               $row_conf['visible'] = TRUE;
 
           else
                $row_conf
['visible'] = FALSE;

 
           if( @$p->required == )
 
               $row_conf['required'] = TRUE;

 
           // Set field list for every Dependent, even if not selected (Incase changed to)
 
           foreach($partition_fields as $pid => $par_field)
 
           {
 
               foreach$par_field['fields'] as $fk => $a )
 
               {
 
                   if( ! @empty($p->dependent))
 
                   {
 
                       if$a['key'] === $p->dependent )
 
                       {
 
                           $partition_fields$pid ]['fields'][ $fk ]['selected'] = 'SELECTED';
 
                       }
 
                       else
                        
{
 
                           $partition_fields$pid ]['fields'][ $fk ]['selected'] = '';
 
                       }
 
                   }
 
                   else
                    
{
 
                       $partition_fields$pid ]['fields'][ $fk ]['selected'] = '';
 
                   }
 
               }
 
           }

 
           $row_conf['fields'] = $partition_fields;

 
           // Set which fields are disabled/enabled
 
           switch$p->type )
 
           {
 
               case 'numeric':
 
                   $row_conf['disable']['regex'      TRUE;
 
                   break;

 
               case 'ipaddr':
 
               case 'macaddr':
 
               case 'timestamp':
 
               case 'time':
 
               case 'date':
 
               case 'phone':
 
                   $row_conf['disable']['regex'      TRUE;
 
                   $row_conf['disable']['min'        TRUE;
 
                   $row_conf['disable']['max'        TRUE;
 
                   break;

 
               case 'url':
 
               case 'email':
 
                   $row_conf['disable']['regex'      TRUE;
 
                   $row_conf['disable']['min'        TRUE;
 
                   break;



 
               case 'multiselect':
 
                   foreach($p->options as $o)
 
                       $row_conf['multiselect_value'][] = array(
 
                           'value'     => $o,
 
                           'select'    => (@in_array($o$p->default) ? 'SELECTED' '')
 
                       );

 
                   $row_conf['disable']['primary'    TRUE;
 
                   $row_conf['disable']['placeholder'] = TRUE;
 
                   $row_conf['disable']['regex'      TRUE;
 
                   $row_conf['regex_helper'          'minus'// Show disabled regex icon
 
                   break;

 
               case 'select':
 
                   foreach($p->options as $o)
 
                       $row_conf['select_value'][] = array(
 
                           'value'     => $o,
 
                           'select'    => ($o == $p->default 'SELECTED' '')
 
                       );

 
                   $row_conf['disable']['primary'    TRUE;
 
                   $row_conf['disable']['placeholder'] = TRUE;
 
                   $row_conf['disable']['regex'      TRUE;
 
                   $row_conf['disable']['min'        TRUE;
 
                   $row_conf['disable']['max'        TRUE;
 
                   $row_conf['regex_helper'          'minus'// Show disabled regex icon
 
                   break;

 
               case 'boolean':
 
                   if($p->default)
 
                       $row_conf['boolean_value'     TRUE;
 
                   $row_conf['disable']['primary'    TRUE;
 
                   $row_conf['disable']['placeholder'] = TRUE;
 
                   $row_conf['disable']['regex'      TRUE;
 
                   $row_conf['disable']['min'        TRUE;
 
                   $row_conf['disable']['max'        TRUE;
 
                   $row_conf['disable']['unique'     TRUE;
 
                   $row_conf['regex_helper'          'minus'// Show disabled regex icon
 
                   break;

 
               case 'text':
 
                   $row_conf['text_value'            $p->default;
 
                   if( @$partition->fields$k ]->primary === '1' )
 
                   {
 
                       $row_conf['disable']['unique' TRUE;
 
                       $row_conf['disable']['required']= TRUE;
 
                   }
 
                   $row_conf['regex_helper'] = 'question'// Show enabled regex icon
 
                   break;

 
               case 'string':
 
                   $row_conf['string_value'           $p->default;
 
                   if( @$partition->fields$k ]->primary === '1' )
 
                   {
 
                       $row_conf['disable']['unique'  TRUE;
 
                       $row_conf['disable']['required'] = TRUE;
 
                   }
 
                   $row_conf['regex_helper'] = 'question'// Show enabled regex icon
 
                   break;

 
               case 'dependent_multiple':
 
               case 'dependent_single':
 
                   $row_conf['disable']['primary'    TRUE;
 
                   $row_conf['disable']['placeholder'] = TRUE;
 
                   $row_conf['disable']['min'        TRUE;
 
                   $row_conf['disable']['max'        TRUE;
 
                   $row_conf['disable']['regex'      TRUE;
 
                   $row_conf$p->type               TRUE;
 
                   $row_conf['regex_helper'          'minus'// Show disabled regex icon
 
                   $row_conf['type_dependent'        $p->type;

 
                   break;
 
           }

 
           foreach($p as $name => $val)
 
           {
 
               $row_conf['values'][$name] = $val;
 
           }

 
           // Render Mustache template
 
           echo $mustache->render'partition_field_row'$row_conf );

 
           $row_id $counter++;
 
       }
 
   }
 
   else
    
{
 
       $row_id 0;

 
       $row_conf = array(
 
           'visible'       => TRUE,
 
           'counter'       => $row_id,
 
           'type_string'   => TRUE,
 
           'fields'        => $partition_fields,
 
           'order'         => 0
        
);

 
       echo $mustache->render'partition_field_row'$row_conf );
 
   }
 
   ?>
    </tbody>
</table> 




Template File (partition_field_row) [External Link]:
Code:
<tr data-row-id="{{counter}}" id="">
   <td>
       {{counter}}
   </td>
   <td class="row-grip">
       <input type="hidden" name="order[]" class="row-order" id="order-{{counter}}" value="{{order}}" />
       <span class="reorder-grip"></span>
   </td>
   <td  class="intro-delete-row">
       <!--<a href="#confirm-field-delete" class="delete-row{{#values.name}}-confirm{{/values.name}}" {{#values.name}}data-toggle="modal"{{/values.name}}>
           <i class="fa fa-times-circle fa-lg"></i>
       </a>-->
       <a href="#" class="delete-row{{#values.name}}-confirm{{/values.name}}">
           <i class="fa fa-times-circle fa-lg"></i>
       </a>
       <div class="align-center display-none">
           {{! If this is a row thats for a field being edited, add the hidden original_name input with the field name, so the PHP knows if it was renamed }}
           {{#column_name}}
           <input type="hidden" class="field-origial-name" name="original_name[]" value="{{column_name}}" />
           {{/column_name}}
           <input type="hidden" class="field-row-id" name="row_id[]" value="{{counter}}">
       </div>
   </td>
   <td class="intro-always-visible">
       <div class="align-center">
           <input type="checkbox" name="visible[]" class="field-setting-visible visible-field labelauty" value="{{counter}}" {{#visible}}checked="checked"{{/visible}}>
       </div>
   </td>
   <td class="intro-primary align-center">
       <input type="radio" name="primary" {{#primary}}checked{{/primary}}  {{#disable.primary}}readonly="readonly"{{/disable.primary}} value="{{counter}}" class="field-setting-primary form-control confirm-radio input-sm labelauty" >
   </td>
   <td class="intro-field_name">
       <input type="text" name="field_name[]" value="{{#values.name}}{{values.name}}{{/values.name}}" data-parsley-error-message="" data-parsley-validateunique=".field-name" class="field-name form-control confirm-str focus-enlarge input-sm width-full" required="" data-focus-width="160px" >
   </td>
   <td class="intro-description">
       <input type="text" name="description[]" value="{{#values.description}}{{values.description}}{{/values.description}}" class="description form-control confirm-str focus-enlarge input-sm width-full" data-focus-width="160px">
   </td>
   <td class="intro-placeholder">
       <input type="text" name="placeholder[]" {{#disable.placeholder}}readonly="readonly"{{/disable.placeholder}} value="{{#values.placeholder}}{{values.placeholder}}{{/values.placeholder}}" class="field-setting-placeholder form-control confirm-str focus-enlarge input-sm width-full" data-focus-width="160px">
   </td>
   <td class="intro-required">
       <input type="checkbox" name="required[]" {{#required}}checked{{/required}} {{#disable.required}}readonly="readonly"{{/disable.required}} value="{{counter}}" class="field-setting-required form-control confirm-check required-field input-sm labelauty" >
   </td>
   <td class="intro-unique">
       <input type="checkbox" name="unique[]" {{#unique}}checked{{/unique}}  {{#disable.unique}}readonly="readonly"{{/disable.unique}}  value="{{counter}}" class="field-setting-unique form-control confirm-check unique-field input-sm labelauty" >
   </td>
   <td class="intro-regex">
       <div class="input-group">
           <input type="text" name="regex[]" {{#disable.regex}}readonly="readonly"{{/disable.regex}} value="{{#values.regex}}{{values.regex}}{{/values.regex}}" class="field-setting-regex form-control confirm-str focus-enlarge input-sm width-full"  data-focus-width="160px"  size="12" data-parsley-errors-container="#parsley-errors-list">
           <span class="input-group-addon">
               <a href="#" class="regex-help-link"  data-toggle="modal">
                   <i id="regex-help-link-{{counter}}" class="regex-help-icon fa fa-{{#disable.regex}}minus{{/disable.regex}}{{^disable.regex}}question{{/disable.regex}}-circle color-{{#disable.regex}}disabled{{/disable.regex}}{{^disable.regex}}normal{{/disable.regex}}"></i>
               </a>
           </span>
       </div>
   </td>
   <td class="intro-min">
       <input type="text" name="min[]" {{#disable.min}}readonly="readonly"{{/disable.min}} size="3"  value="{{#values.min}}{{values.min}}{{/values.min}}" class="field-setting-min form-control confirm-str focus-enlarge input-sm" data-focus-width="80px" >
   </td>
   <td class="intro-max">
       <input type="text" name="max[]" {{#disable.max}}readonly="readonly"{{/disable.max}} size="3"  value="{{#values.max}}{{values.max}}{{/values.max}}" class="field-setting-max form-control confirm-str focus-enlarge input-sm" data-focus-width="80px" >
   </td>
   <td class="intro-type">
       <select name="type[]" {{#current_type}}data-current-type="{{current_type}}"{{/current_type}} class="field-setting-type field-type width-100 form-control confirm-str input-sm" data-parsley-error-message="" required="" data-parsley-verifytype="{{counter}}" >
       <option value="string" {{#type_string}}selected="selected"{{/type_string}}>String</option>
       <option value="text" {{#type_text}}selected="selected"{{/type_text}}>Text</option>
       <option value="select" {{#type_select}}selected="selected"{{/type_select}}>Select</option>
       <option value="multiselect" {{#type_multiselect}}selected="selected"{{/type_multiselect}}>Multi Select</option>
       <option value="boolean" {{#type_boolean}}selected="selected"{{/type_boolean}}>Boolean</option>
       {{#fields.0}}<option value="dependent" {{#type_dependent}}selected="selected"{{/type_dependent}}>Dependent</option>{{/fields.0}}
       <option value="email" {{#type_email}}selected="selected"{{/type_email}}>E-Mail</option>
       <option value="url" {{#type_url}}selected="selected"{{/type_url}}>URL</option>
       <option value="phone" {{#type_phone}}selected="selected"{{/type_phone}}>Telephone #</option>
       <option value="numeric" {{#type_numeric}}selected="selected"{{/type_numeric}}>Numeric/Integer</option>
       <option value="date" {{#type_date}}selected="selected"{{/type_date}}>Date</option>
       <option value="time" {{#type_time}}selected="selected"{{/type_time}}>Time</option>
       <option value="timestamp" {{#type_timestamp}}selected="selected"{{/type_timestamp}}>Timestamp</option>
       <option value="ipaddr" {{#type_ipaddr}}selected="selected"{{/type_ipaddr}}>IP Address</option>
       <option value="macaddr" {{#type_macaddr}}selected="selected"{{/type_macaddr}}>MAC Address</option>
       </select>
   </td>
   <td class="intro-value">
       <div class="position-relative">
           <!-- String Field Value -->
           <div class="{{#type_string}}display-block{{/type_string}}{{^type_string}}display-none{{/type_string}} type-string" >
               <input type="text" name="string[]" value="{{#string_value}}{{string_value}}{{/string_value}}" class="field-value form-control string-value width-full input-sm focus-enlarge" data-focus-width="200px" data-prefocus-width="full">
           </div>
           <!-- Text Field Value -->
           <div class="{{#type_text}}display-block{{/type_text}}{{^type_text}}display-none{{/type_text}} type-text">
               <textarea name="text[]" class="field-value form-control width-full input-sm focus-enlarge" data-focus-width="200px" data-prefocus-width="160px">{{#text_value}}{{text_value}}{{/text_value}}</textarea>
           </div>
           <!-- Select Field Value -->
           <div class="{{#type_select}}display-block{{/type_select}}{{^type_select}}display-none{{/type_select}} type-select">
               <select name="select_{{counter}}[]" class="field-value select form-control width-full input-sm" id="selectbox_{{counter}}">
                   {{#select_value}}
                   <option value="{{value}}" data-legacy-option="true" data-original="{{value}}" {{select}}>{{value}}</option>
                   {{/select_value}}
               </select>
               <select name="selectAll_{{counter}}[]" class="multiselectAll display-none" id="selectbox_{{counter}}_all" multiple="">
                   {{#select_value}}
                   <option value="{{value}}" data-legacy-option="true" data-original="{{value}}">{{value}}</option>
                   {{/select_value}}
               </select>
               <span title="Add a new value" class="lgutipT f-s-11">
                   <a href="#" class="add-select-option"  data-type="select">
                       <i class="fa fa-plus-square-o"></i> Add
                   </a>
               </span>
               / <span title="Remove selected values" class="lgutipT f-s-11">
                   <a href="#" class="delete-selected-options"  data-type="select">
                       <i class="fa fa-minus-square-o"></i> Del
                   </a>
               </span>
               / <span title="Rename selected value" class="lgutipT f-s-11">
                   <a href="#" class="rename-selected-options"  data-type="select" {{#column_name}}data-column-name="{{column_name}}"{{/column_name}}>
                       <i class="fa fa-pencil-square-o"></i> Rename
                   </a>
               </span>
           </div>
           <!-- Multiselect Field Value -->
           <div class="{{#type_multiselect}}display-block{{/type_multiselect}}{{^type_multiselect}}display-none{{/type_multiselect}} type-multiselect">
               <select name="multiselect_{{counter}}[]" class="field-value multiselect form-control width-full input-sm" id="multiselectbox_{{counter}}" multiple="">
                   {{#multiselect_value}}
                   <option value="{{value}}" data-legacy-option="true" data-original="{{value}}" {{select}}>{{value}}</option>
                   {{/multiselect_value}}
               </select>
               <select name="multiselectAll_{{counter}}[]" class="multiselectAll display-none" id="multiselectbox_{{counter}}_all" multiple="">
                   {{#multiselect_value}}
                   <option value="{{value}}" data-legacy-option="true" data-original="{{value}}">{{value}}</option>
                   {{/multiselect_value}}
               </select>
               <span title="Add a new value" class="lgutipT f-s-11">
                   <a href="#" class="add-select-option"  data-type="multiselect">
                       <i class="fa fa-plus-square-o"></i> Add
                   </a>
               </span>
               / <span title="Remove selected values" class="lgutipT f-s-11">
                   <a href="#" class="delete-selected-options"  data-type="multiselect">
                       <i class="fa fa-minus-square-o"></i> Del
                   </a>
               </span>
               / <span title="Rename selected value" class="lgutipT f-s-11">
                   <a href="#" class="rename-selected-options"  data-type="multiselect" {{#column_name}}data-column-name="{{column_name}}{{/column_name}}">
                       <i class="fa fa-pencil-square-o"></i> Rename
                   </a>
               </span>
           </div>
           <!-- Boolean Field Value -->
           <div class="{{#type_boolean}}display-block{{/type_boolean}}{{^type_boolean}}display-none{{/type_boolean}} type-boolean">
               <input type="checkbox" name="boolean[]" value="{{counter}}" class="field-value input-sm width-full" {{#boolean_value}}checked{{/boolean_value}}>
           </div>
           <!-- Dependent Field Value -->
           <div class="{{#type_dependent}}display-block{{/type_dependent}}{{^type_dependent}}display-none{{/type_dependent}} type-dependent">
               <select name="dependent[]" class="field-value select form-control width-full input-sm" id="dependent-{{counter}}">
                   <option value="">-- Select --</option>
                   {{#fields}}
                   <optgroup label="{{partition}}">
                       {{#fields}}
                       <option value="{{key}}" {{#selected}}{{selected}}{{/selected}}>{{val}}</option>
                       {{/fields}}
                   </optgroup>
                   {{/fields}}
               </select>
               <span class="f-s-10 display-block">
                   <strong>Type:</strong>
                   <label class="m-l-8 "><!-- @todo WHY WONT THIS CHECK -->
                       <input type="radio" name="dependent_type_{{counter}}" value="single" {{^dependent_multiple}}checked{{/dependent_multiple}}> Single
                   </label>
                   <label class="m-l-8">
                       <input type="radio" name="dependent_type_{{counter}}" value="multiple" {{#dependent_multiple}}checked{{/dependent_multiple}}> Multiple
                   </label>
               </span>
           </div>
           <!-- E-Mail Field Value -->
           <div class="{{#type_email}}display-block{{/type_email}}{{^type_email}}display-none{{/type_email}} type-email">
               <input type="text" name="email[]" value="{{#email_value}}{{email_value}}{{/email_value}}" placeholder="EG: [email protected]" class="field-value form-control email-value width-full input-sm focus-enlarge" data-focus-width="200px" data-prefocus-width="full">
           </div>
           <!-- URL Field Value -->
           <div class="{{#type_url}}display-block{{/type_url}}{{^type_url}}display-none{{/type_url}} type-url">
               <input type="text" name="url[]" value="{{#url_value}}{{url_value}}{{/url_value}}" placeholder="EG: http://www.someurl.com/" class="field-value form-control url-value width-full input-sm focus-enlarge" data-focus-width="200px" data-prefocus-width="full">
           </div>
           <!-- Phone Field Value -->
           <div class="{{#type_phone}}display-block{{/type_phone}}{{^type_phone}}display-none{{/type_phone}} type-phone">
               <input type="text" name="phone[]" value="{{#phone_value}}{{phone_value}}{{/phone_value}}" placeholder="EG: (602) 123-4567" class="field-value form-control phone-value width-full input-sm focus-enlarge" data-focus-width="150px" data-prefocus-width="full">
           </div>
           <!-- Numeric/Int Field Value -->
           <div class="{{#type_numeric}}display-block{{/type_numeric}}{{^type_numeric}}display-none{{/type_numeric}} type-numeric">
               <input type="text" name="numeric[]" value="{{#numeric_value}}{{numeric_value}}{{/numeric_value}}" class="field-value form-control numeric-value width-full input-sm">
           </div>
           <!-- Date Field Value -->
           <div class="{{#type_date}}display-block{{/type_date}}{{^type_date}}display-none{{/type_date}} type-date">
               <input type="text" name="date[]" value="{{#date_value}}{{date_value}}{{/date_value}}" placeholder="EG: mm/dd/yyyy" class="field-value form-control date-value width-full input-sm">
           </div>
           <!-- Time Field Value -->
           <div class="{{#type_time}}display-block{{/type_time}}{{^type_time}}display-none{{/type_time}} type-time">
               <input type="text" name="time[]" value="{{#time_value}}{{time_value}}{{/time_value}}" placeholder="EG: 12:00 AM" class="field-value form-control time-value width-full input-sm ">
           </div>
           <!-- Timestamp Field Value -->
           <div class="{{#type_timestamp}}display-block{{/type_timestamp}}{{^type_timestamp}}display-none{{/type_timestamp}} type-timestamp">
               <input type="text" name="timestamp[]" value="{{#timestamp_value}}{{timestamp_value}}{{/timestamp_value}}" placeholder="EG: 2015-07-07 08:30" class="field-value form-control timestamp-value width-full input-sm">
           </div>
           <!-- IP Address Field Value -->
           <div class="{{#type_ipaddr}}display-block{{/type_ipaddr}}{{^type_ipaddr}}display-none{{/type_ipaddr}} type-ipaddr">
               <input type="text" name="ipaddr[]" value="{{#ipaddr_value}}{{ipaddr_value}}{{/ipaddr_value}}" placeholder="EG: 75.170.120.40" class="field-value form-control ipaddr-value width-full input-sm">
           </div>
           <!-- MAC Address Field Value -->
           <div class="{{#type_macaddr}}display-block{{/type_macaddr}}{{^type_macaddr}}display-none{{/type_macaddr}} type-macaddr">
               <input type="text" name="macaddr[]" value="{{#macaddr_value}}{{macaddr_value}}{{/macaddr_value}}" placeholder="EG: 00:12:0A:1A:B2:BB" class="field-value form-control macaddr-value width-full input-sm">
           </div>
       </div>
   </td>
</tr>


It's terrible, I know, it pretty much voids the entire point of a view file, too much logic. But putting that logic in the controller is JUST as messy. 

The solution may be to use a better template engine that supports logic, but it must be able to render the same template in PHP and jQuery/JS.


The ones I found are If you cant think of a way to slim down that view file, and know any of the above template engines, lmk which ones you think might suit the situation best.

Thanks
Reply

#6
(09-23-2015, 10:25 AM)jLinux Wrote: What I usually do is basically the same, You can shorten up that ternary operator by not adding the first $something, I believe its in PHP >= 5.3

And since I'm requiring my app to have PHP >= 5.4, I can use the PHP open tags, without having to worry about if its enabled or not.

So I just do...


PHP Code:
<input value="<?=(@$something ?: 'safe default value')?>"/> 

You can shorten up the ternary operator, but there are situations in which

Code:
isset($something) ? $something : 'safe default value'

is not the same as

Code:
$something ?: 'safe default value'

For example, when $something is an empty string/array, false, 0, or '0'. Additionally, you shouldn't need the parentheses, unless the short echo tags are doing something weird to the order of operations. I do use the short form of the ternary operator when I feel it's appropriate/safe to do so, but the only way to really know that is to know what the possible values are for that variable.

I don't use short echo tags, regardless of the version of PHP I'm using, especially since they have to be converted to full open tags + echo statements if I have to add additional code to that location later. It's mostly a personal preference, but I find it easier to deal with long-term maintenance if the tags are consistent throughout the application.

I would say the same about a lot of other shortcuts enabled by the language, like omitting semicolons and curly braces where permitted. I usually just feel the small number of extra characters I have to use initially can save me (or someone else) from hard-to-find issues in the future.

Note that short open tags still won't work if short_open_tag is disabled, it's only the short echo tags which will work.

(09-23-2015, 10:25 AM)jLinux Wrote: I do however, have a very very very nasty view file, which has WAY more PHP than it should. one reason is that it parses a mustache template (I chose mustache because I needed a template that could be parsed in PHP AND jQuery).

I'll probably take a look at it, but there's obviously a lot there, and though I have a basic understanding of mustache templates, I don't use them, so it's possible that I would miss something obvious.
Reply

#7
(09-23-2015, 11:27 AM)mwhitney Wrote: I'll probably take a look at it, but there's obviously a lot there, and though I have a basic understanding of mustache templates, I don't use them, so it's possible that I would miss something obvious.

Im looking at jquery-tmpl (for jQuery and PHP), I might switch from Mustache over to that... 

I get logic-less templates are a good idea, but when it comes down to either logic-less templates and PHP in views, or no PHP in views and logic templates... ill take logic templates.

Esp since the same PHP logic you see there, I have running for when the row is inserted via jQuery
Reply

#8
Honestly, when your table's row template is 200+ lines and you have nearly 200 lines of code (or maybe 200+, depending on how you format it) in a loop to prep the data passed from the controller to fit into that template, it means that either something went horribly wrong before you even got to the view, or the table is just too complicated for a simple view.

On the other hand, I can't help but think that some of the template is overly-complicated (I can only assume to simplify the script and CSS applied to it) and that it's sometimes harder to do something in a template than in either PHP or JavaScript.
Reply

#9
@jLinux

If you stay with Mustache templates, you need something between the controller and the Mustache view to convert the data by using visually-oriented logic. You can use:

1. An external library that supports presenters, (for example https://github.com/druu/ci-presenter). Unfortunately CodeIgniter does not implement presenters for now.
2. Or models with data-conversion-to-mustache purpose - this is what I've tried so far.
Reply

#10
(09-23-2015, 02:01 PM)mwhitney Wrote: Honestly, when your table's row template is 200+ lines and you have nearly 200 lines of code (or maybe 200+, depending on how you format it) in a loop to prep the data passed from the controller to fit into that template, it means that either something went horribly wrong before you even got to the view, or the table is just too complicated for a simple view.

On the other hand, I can't help but think that some of the template is overly-complicated (I can only assume to simplify the script and CSS applied to it) and that it's sometimes harder to do something in a template than in either PHP or JavaScript.
I didnt really plan for it to get like that, lol. 

basically, I have the same view for editing/creating "partitions", so when you create a new one, you can click the Add Row button, and it adds rows to the table with new settings., those rows are added via jQuery from the template. 

Now that you created the "partition", when you go to edit it, those same rows are populated in the table, this time by PHP, but from the same template file, and you can add more rows via JS, also using the same template file... see why I wanted JS AND PHP template parser?

The rows have check boxes, links, buttons, radios, inputs, etc, so when the new rows are added, the php passes an array of the row settings to the template, and since the template is logic-less... its very messy..

Heres what the table looks like when its populated, you can see why it gets a little outa hand.
[Image: NzLH?response-content-disposition=inline...M3LSMN33SA]

I realize that this would be a lot less work using something like Angular, but im already so far into version 1.0, im just going to get this out, then ill work on 2.0, which will be much more stable and optimized (Laravel and Angular probably)
Reply


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.