Overriding Library Parser Di Codeigniter 4
By Harjito
Overriding Library Parser Di Codeigniter 4
Bagi kalia yang biasa menggunakan template engine seperti twig, smarty, blade tentu familier dengan penulisan variabel dan juga loop variabel. CodeIgniter 4 hadir dengan sebuah parser, sebuah lightweight parser yang menyerupai template engine. Tentnya parser ini tidak se-powerfull template engine. Untuk memperkaya parser, disediakan filter dan plugin yang memiliki fungsi seperti helper, karena skript php tidak bisa bekerja dalam parser.
Namun demikian saya menemukan 2 kelemahan dari parser.
- Parser akan error ketika kita menuliskan kurung dalam view
- Plugin tidak bisa melewatkan variabel
Kelemahan tersebut berdasarkan investigasi yang saya lakukan disebabakan
- penggunaan kurung kurawal tunggal untuk variabel, sebagaimana kita ketahui kebanyakan parser menggunakan dobel kurung kurawal
- loop variabel dilakukan setelah plugin
Sebagai contoh jika kita mennuliskan scipt berikut akan menyebabkan error
<td>Nama (Nama ditulis lengkap dengan gelar):</td> {nama} </td>
Agar tidak error, kita harus menulis seperti ini
<td>Nama {noparse}(Nama ditulis lengkap dengan gelar){/noparse}:</td> {nama} </td>
Contoh kedua, script berikut akan menyebabkan error.
<td>Daftar Pilihan </td><td><select>{+ option current="{current_value}" option={options} +}</td>
Solusi yang saya tawarkan cukup mudah yaitu melakukan override method parser pada class \CodeIgniter\View\Parser. Berikut script tersebut sebagai berikut.
<?php
namespace App\Libraries;
use CodeIgniter\View\Parser;
use CodeIgniter\View\Exceptions\ViewException;
use Config\View as ViewConfig;
use ParseError;
use Psr\Log\LoggerInterface;
/**
* Layout
*/
class MyParser extends \CodeIgniter\View\Parser
{
public function __construct()
{
$viewConfig = new \Config\View();
$viewPath = APPPATH . 'Views/';
$loader = \Config\Services::loader();
$debug = CI_DEBUG;
$logger = \Config\Services::logger();
parent::__construct($viewConfig, $viewPath, $loader , $debug, $logger);
}
/**
* Parse a template
*
* Parses pseudo-variables contained in the specified template,
* replacing them with the data in the second param
*
* @param array $options Future options
*/
protected function parse(string $template, array $data = [], ?array $options = null): string
{
if ($template === '') {
return '';
}
// Remove any possible PHP tags since we don't support it
// and parseConditionals needs it clean anyway...
$template = str_replace(['<?', '?>'], ['<?', '?>'], $template);
$template = str_replace(['(', ')'], ['#40', '#41'], $template);
// temporarily replace the plugin tag so it doesn't trigger an error during the loop
$template = str_replace(['{+', '+}'], ['#$', '$#'], $template);
$template = $this->parseComments($template);
$template = $this->extractNoparse($template);
// Replace any conditional code here so we don't have to parse as much
$template = $this->parseConditionals($template);
// loop over the data variables, replacing
// the content as we go.
foreach ($data as $key => $val) {
$escape = true;
if (is_array($val)) {
$escape = false;
$replace = $this->parsePair($key, $val, $template);
} else {
$replace = $this->parseSingle($key, (string) $val);
}
foreach ($replace as $pattern => $content) {
$template = $this->replaceSingle($pattern, $content, $template, $escape);
}
}
// return plugin tag before running parsePlugins
$template = str_replace(['#$', '$#'], ['{+', '+}'], $template);
// Handle any plugins before normal data, so that
// it can potentially modify any template between its tags.
$template = $this->parsePlugins($template);
$template = $this->insertNoparse($template);
$template = str_replace(['#40', '#41'], ['(', ')'], $template);
return $template;
}
}
Dengan override method parse maka penulisan berikut tidak kan mengalami error.
<td>Nama (Nama ditulis lengkap dengan gelar):</td> {nama} </td>
<td>Daftar Pilihan </td><td><select>{+ option current="{current_value}" option={options} +}</td>
Tags:
Ikuti terus tutorial saya di e-Project dan channel
saya di