What is the most convenient approach for generating Javascript / ExtJS code with PHP?

I am creating a PHP framework that allows a PHP developer to create an ExtJS front-end with only PHP classes, for example. meshing is as follows:

$grid_import = new Backend_Layout_Grid('smart_worksheets'); $grid_import->set_width(1300); $grid_import->set_rows_selectable(true); $grid_import->set_title(__('backend.application.import.grid.title')); $grid_import->set_margin('10px'); //CSS syntax, eg also "10px 0 0 0" $grid_import->add_column(array('id_code'=>'name', 'label'=> __('backend.application.import.worksheetstoimport'), 'width'=>'300')); $grid_import->add_column(array('id_code'=>'kind', 'label'=> __('backend.application.import.kind'), 'width'=>'50')); $grid_import->add_column(array('id_code'=>'file_size', 'label'=> __('backend.application.import.sizebyte'), 'datatype' => 'int')); $grid_import->add_column(array('id_code'=>'when_file_copied', 'label'=> __('backend.application.import.whenfilecopied'), 'datatype' => 'datetime', 'width'=>'150')); $grid_import->add_column(array('id_code'=>'table_name', 'label'=> __('backend.application.import.mysqltablename'), 'width'=>'300')); $grid_import->add_column(array('id_code'=>'when_table_created', 'label'=> __('backend.application.import.whentablecreated'), 'width'=>'160')); $grid_import->add_column(array('id_code'=>'status', 'label'=> __('backend.application.import.status'), 'width'=>'300')); $grid_import->set_doubleclick_target_uri('backend/application/importmanager/single', 0); if (count($smart_worksheets) > 0) { $row_index = 0; foreach ($smart_worksheets as $smart_worksheet) { $show_row = array( 'name' => $smart_worksheet['name'], 'kind' => $smart_worksheet['kind'], 'file_size' => $smart_worksheet['file_size'], 'when_file_copied' => $smart_worksheet['when_file_copied'], 'table_name' => $smart_worksheet['table_name'], 'when_table_created' => __($smart_worksheet['when_table_created']), 'status' => __($smart_worksheet['status']) ); $grid_import->add_row($show_row); if(in_array($smart_worksheet['status'], array('backend.application.import.status.needtoimport', 'backend.application.import.status.needtoreimport'))) { $grid_import->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->add_row_format($row_index, Backend_Layout_Grid::ROW_FORMAT_GREEN); } if(intval($smart_worksheet['file_size']) > 4000000 AND (in_array($smart_worksheet['kind'], array('XLS','XLSX')))) { $grid_import->add_row_format($row_index, Backend_Layout_Grid::ROW_FORMAT_GRAY); } $row_index++; } } Backend_Layout_Window::instance()->add_item($grid_import); 

It works well so far, but since I am simply outputting javascript code in turn, the more functions I embed in a class, the more difficult the if / then logic arises in creating raw Javascript text, here is a typical method that generates Javascript code:

 public function render_main_code_block() { $retval = ''; $retval .= $this->render_data_variable(); $retval .= $this->render_array_reader_block(); $retval .= $this->render_grid_panel_block(); if($this->rows_selectable) { $retval .= self::render_line("````}),"); $retval .= self::render_line("````sm: sm,"); } $retval .= self::render_line("````viewConfig: {"); if ($this->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->row_formats) > 0) { foreach ($this->row_formats as $row_index => $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->title',"); if ( ! is_null($this->width)) { $retval .= self::render_line("````width: $this->width,"); } $retval .= $this->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->script_variable_name.");"); $retval .= self::render_line("``".$this->script_variable_name.".getSelectionModel().selectFirstRow();"); // for word wrapping in columns $retval .= self::render_line("``function columnWrap(val){"); $retval .= self::render_line("````return '<div style=\"white-space:normal !important;\">'+ val +'</div>';"); $retval .= self::render_line("``}"); return $retval; } 

Some specific problems that are starting to make this code too difficult to maintain:

  • The simple fact is that in the property lists, only the last element has no comma . So far, I have managed to set the required properties at the end of the list to always include a decimal point.

enter image description here

  • and some functions (such as adding flags to the grid or not) require code to be inserted in four different places in javascript code , and I can imagine that there are functions that require code to be restructured, so if the function is enabled, the surrounding code must be, for example, contained in another section of the object

So, at some point I want a refactor to create Javascript.

Currently, I see only one option to create, for example. a CodeFactory , which contains, for example, ExtJsVariable , to which I add objects that contain the objects themselves recursively, objects can be of type, for example. simpleArray or anonymousFunction , etc., and then to create the code, I would $codeFactory->render() , which would give me code based on all its internal objects:

enter image description here

What are the other options or code generation frameworks that I could use to generate this Javascript / ExtJS code with PHP more convenient and understandable?

+4
source share
3 answers

The best way is to avoid generating JS as much as possible and save all Javascript in static JS files (e.g. factories, assemblers in your case). And feed them with JSON data generated from the server. This will greatly improve the structure and simplify your application. You can read about Factory and Builder patterns.

+2
source

In fact, I went through a similar way to create ExtJS code with PHP, or in particular from CakePHP.

In my company, I am responsible for creating the framework of the application, which will accelerate the production of applications, so I actually go out with our first generation database, which is similar to your idea: code generation via PHP.

Then quickly, I realize that this is pretty hard for the server and slows down. Each request that you need needs to recover codes, which is impractical. Shortly after I came out with the second generation, with the ability to cache. Generated JS codes get cached into static files and dynamically included if necessary. The reason for caching is that most of the time, JS codes are static, the changes are content, storage, etc.

So, this method works a couple of months, until I finally understand that this is not the right way, for example,

  • TreePanel cannot be generated this way, especially with a dynamic menu.
  • ACL cannot interfere with cached code
  • Cannot have dynamic columns in grid
  • My infrastructure is poorly developed, so I need to cache the codes before I see the result - slow development.
  • Hard to maintain, hard to call. Simple things like adding one configuration or deleting one configuration can be tedious. Just like it is tiring to use FormHelper to complete simple things.

So, I completely rewrote my code base, redesigned everything until I came up with this beautiful ExtJS + CakePHP framework, which:

  • The general components of GridPanel / Store / View / Pagination / Editor were created, and with a simple configuration you get a complete REST grid that connects to one of the Cake controllers. In Cake, you include one of the specially designed component, and with just a few lines of code you have created a complete working REST grid.
  • Specially designed Viewport, which provides a similar appearance, with a specially designed TreePanel (Menu), TabPanel (Contents)
  • And many other common, useful components are packaged together, such as Wizard, FieldEditor, UserImport ... etc.
  • And since they are all extJS extensible components, you can use it, extend it, fully customize it for whatever you want.

Sorry if this does not suit you, but I personally went through this, and I am really unhappy with the result of generating the code with PHP. You basically end up complicating the whole process or slowing down the work.

Sorry for my bad english, by the way. And thanks for that.

And I can’t share my code and open source, because it is part of the company’s property.

0
source

I would make some suggestions as I made some of them.

First of all, move as much as you can to the library classes. Secondly, you can create a PHP data structure and turn it into JSON using json_encode

And finally, keep it simple!

0
source

Source: https://habr.com/ru/post/1337312/


All Articles