Note that there are some explanatory texts on larger screens.

plurals
  1. POWhat is the most maintainable approach to generating Javascript/ExtJS code from PHP?
    primarykey
    data
    text
    <p>I'm creating a PHP framework which allows a PHP developer to create an ExtJS front end with PHP classes only, e.g. creating a grid looks like this:</p> <pre><code>$grid_import = new Backend_Layout_Grid('smart_worksheets'); $grid_import-&gt;set_width(1300); $grid_import-&gt;set_rows_selectable(true); $grid_import-&gt;set_title(__('backend.application.import.grid.title')); $grid_import-&gt;set_margin('10px'); //CSS syntax, e.g. also "10px 0 0 0" $grid_import-&gt;add_column(array('id_code'=&gt;'name', 'label'=&gt; __('backend.application.import.worksheetstoimport'), 'width'=&gt;'300')); $grid_import-&gt;add_column(array('id_code'=&gt;'kind', 'label'=&gt; __('backend.application.import.kind'), 'width'=&gt;'50')); $grid_import-&gt;add_column(array('id_code'=&gt;'file_size', 'label'=&gt; __('backend.application.import.sizebyte'), 'datatype' =&gt; 'int')); $grid_import-&gt;add_column(array('id_code'=&gt;'when_file_copied', 'label'=&gt; __('backend.application.import.whenfilecopied'), 'datatype' =&gt; 'datetime', 'width'=&gt;'150')); $grid_import-&gt;add_column(array('id_code'=&gt;'table_name', 'label'=&gt; __('backend.application.import.mysqltablename'), 'width'=&gt;'300')); $grid_import-&gt;add_column(array('id_code'=&gt;'when_table_created', 'label'=&gt; __('backend.application.import.whentablecreated'), 'width'=&gt;'160')); $grid_import-&gt;add_column(array('id_code'=&gt;'status', 'label'=&gt; __('backend.application.import.status'), 'width'=&gt;'300')); $grid_import-&gt;set_doubleclick_target_uri('backend/application/importmanager/single', 0); if (count($smart_worksheets) &gt; 0) { $row_index = 0; foreach ($smart_worksheets as $smart_worksheet) { $show_row = array( 'name' =&gt; $smart_worksheet['name'], 'kind' =&gt; $smart_worksheet['kind'], 'file_size' =&gt; $smart_worksheet['file_size'], 'when_file_copied' =&gt; $smart_worksheet['when_file_copied'], 'table_name' =&gt; $smart_worksheet['table_name'], 'when_table_created' =&gt; __($smart_worksheet['when_table_created']), 'status' =&gt; __($smart_worksheet['status']) ); $grid_import-&gt;add_row($show_row); if(in_array($smart_worksheet['status'], array('backend.application.import.status.needtoimport', 'backend.application.import.status.needtoreimport'))) { $grid_import-&gt;add_row_format($row_index, Backend_Layout_Grid::ROW_FORMAT_RED); } if(in_array($smart_worksheet['status'], array('backend.application.import.status.isuptodate'))) { $grid_import-&gt;add_row_format($row_index, Backend_Layout_Grid::ROW_FORMAT_GREEN); } if(intval($smart_worksheet['file_size']) &gt; 4000000 AND (in_array($smart_worksheet['kind'], array('XLS','XLSX')))) { $grid_import-&gt;add_row_format($row_index, Backend_Layout_Grid::ROW_FORMAT_GRAY); } $row_index++; } } Backend_Layout_Window::instance()-&gt;add_item($grid_import); </code></pre> <p>It works well so far, but since I am just outputting javascript code line-by-line, the more features I build into the class, the more complex the if/then logic gets in building the raw Javascript text, here is a <strong>typical method</strong> which generates the Javascript code:</p> <pre><code>public function render_main_code_block() { $retval = ''; $retval .= $this-&gt;render_data_variable(); $retval .= $this-&gt;render_array_reader_block(); $retval .= $this-&gt;render_grid_panel_block(); if($this-&gt;rows_selectable) { $retval .= self::render_line("````}),"); $retval .= self::render_line("````sm: sm,"); } $retval .= self::render_line("````viewConfig: {"); if ($this-&gt;percentage_columns) { $retval .= self::render_line("``````forceFit: true,"); // true = percentage column width (add up to 100) } else { $retval .= self::render_line("``````forceFit: false,"); } $retval .= self::render_line("``````getRowClass: function(record, rowIndex, rp, ds){"); if (count($this-&gt;row_formats) &gt; 0) { foreach ($this-&gt;row_formats as $row_index =&gt; $row_format) { $retval .= self::render_line("````````if(rowIndex == ".$row_index."){"); $retval .= self::render_line("``````````return '".$row_format."';"); $retval .= self::render_line("````````}"); } } $retval .= self::render_line("````````return '';"); $retval .= self::render_line("``````}"); $retval .= self::render_line("````},"); $retval .= self::render_line("````title: '$this-&gt;title',"); if ( ! is_null($this-&gt;width)) { $retval .= self::render_line("````width: $this-&gt;width,"); } $retval .= $this-&gt;render_double_click_handler(); $retval .= self::render_line("````autoHeight: true,"); $retval .= self::render_line("````frame: true"); $retval .= self::render_line("``});"); $retval .= self::render_line(""); $retval .= self::render_line("``replaceComponentContent(targetRegion, ".$this-&gt;script_variable_name.");"); $retval .= self::render_line("``".$this-&gt;script_variable_name.".getSelectionModel().selectFirstRow();"); // for word wrapping in columns $retval .= self::render_line("``function columnWrap(val){"); $retval .= self::render_line("````return '&lt;div style=\"white-space:normal !important;\"&gt;'+ val +'&lt;/div&gt;';"); $retval .= self::render_line("``}"); return $retval; } </code></pre> <p>Some particular issues which is starting to make this code too complex to maintain is:</p> <ul> <li>the simple fact that in lists of properties, only the <strong>last item does not have a comma</strong>. So far, I have been able to put have required properties at the end of the list so that the item without the comma is always included.</li> </ul> <p><img src="https://i.stack.imgur.com/s2bXN.png" alt="enter image description here"></p> <ul> <li>and some features (such as adding checkboxes to a grid or not) <strong>require code insertions in up to four different places in the javascript code</strong>, and I can imagine there are features which will require the existing code to be restructured, so if the feature is turned on, the surrounding code needs to be e.g. contained within another section of the object</li> </ul> <p>So at some point I want to <strong>refactor</strong> the way I create the Javascript.</p> <p>I currently see only <strong>one option really</strong>, to create e.g. a <code>CodeFactory</code> class which contains e.g. <code>ExtJsVariable</code> to which I add objects which contain objects themselves recursively, the objects can be of type e.g. <code>simpleArray</code> or <code>anonymousFunction</code> etc, and then to create the code I would output <code>$codeFactory-&gt;render()</code> which would give me the code based on all of its internal objects:</p> <p><img src="https://i.stack.imgur.com/frynx.png" alt="enter image description here"></p> <p><strong>What are other options or code generation frameworks I could use to make the generation of this Javascript/ExtJS code from PHP more maintainable and straightforward?</strong></p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload