Dalam artikel terakhir saya, saya terakhir kali membahas pembuatan ekstensi Twig yang akan mengembalikan template untuk diperluas guna mengekstrak logika keputusan dari template. Untuk menyederhanakan contoh, nama templat hanya disimpan dalam konstanta kelas; saya sebutkan bahwa ini dapat dipindahkan ke dalam konfigurasi. Ada beberapa permintaan untuk rincian lebih lanjut tentang cara melakukan ini, jadi ini dia. Ini tidak spesifik untuk ekstensi Twig, tetapi ini memberi kita contoh dalam melihat konfigurasi suite publik.
Jadi mulailah dengan kategori ekstensi seperti ini:
namespace Acme\DemoBundle\Twig;
class DemoExtension extends \Twig_Extension
{
const FULL_TEMPLATE = '::full-layout.html.twig';
const PARTIAL_TEMPLATE = '::partial-layout.html.twig';
public function getFunctions()
{
return array(
'parent_template' => new \Twig_Function_Method($this, 'getParentTemplate'),
);
}
public function getParentTemplate()
{
if ($this->useFullTemplate()) {
return self::FULL_TEMPLATE;
}
return self::PARTIAL_TEMPLATE;
}
public function useFullTemplate()
{
//...
}
}
Dengan definisi layanan ini:
Karena kita hanya mempunyai beberapa nama templat, kita dapat memasukkannya satu per satu ke dalam konstruktor:
namespace Acme\DemoBundle\Twig;
class DemoExtension extends \Twig_Extension
{
private $fullTemplate;
private $partialTemplate;
public function __construct($fullTemplate, $partialTemplate)
{
$this->fullTemplate = $fullTemplate;
$this->partialTemplate = $partialTemplate;
}
public function getFunctions()
{
return array(
'parent_template' => new \Twig_Function_Method($this, 'getParentTemplate'),
);
}
public function getParentTemplate()
{
if ($this->useFullTemplate()) {
return $this->fullTemplate;
}
return $this->partialTemplate;
}
public function useFullTemplate()
{
//...
}
}
Dan atur sebagai parameter dalam file layanan kami:
::full-layout.html.twig
::partial-layout.html.twig
%acme.templates.full%
%acme.templates.partial%
Namun, akan lebih baik jika kita hanya menerima array asosiatif dari nama template sehingga kita dapat menambah jumlahnya nanti tanpa menambah jumlah argumen konstruktor:
namespace Acme\DemoBundle\Twig;
class DemoExtension extends \Twig_Extension
{
private $templates;
public function __construct($templates)
{
$this->templates = $templates;
}
public function getFunctions()
{
return array(
'parent_template' => new \Twig_Function_Method($this, 'getParentTemplate'),
);
}
public function getParentTemplate()
{
if ($this->useFullTemplate()) {
return $this->templates['full'];
}
return $this->templates['partial'];
}
public function useFullTemplate()
{
//...
}
}
::full-layout.html.twig
::partial-layout.html.twig
%acme.templates.full%
%acme.templates.partial%
Sejauh ini hanya menggunakan parameter yang ditetapkan secara langsung, tetapi hal itu tidak memberi kita banyak kesempatan untuk memverifikasi konfigurasi. Saat ini, parameter juga disetel di suite kami. Jika menurut kami bundel tersebut layak untuk dibagikan antar aplikasi, maka kami ingin dapat menyetel parameter di luar bundel dalam konfigurasi tingkat aplikasi. Kita dapat langsung menyimpan pengaturan parameter ini dan kemudian mengaturnya di file parameter aplikasi:
# app/config/config.yml
parameters:
acme.templates:
full: "::full-layout.html.twig"
partial: "::partial-layout.html.twig"
Ini masih tidak memberi kita banyak kendali atas nilai yang kita tetapkan. Kami dapat memvalidasi nilai-nilai ini jika kami menjadikannya bagian dari konfigurasi yang dipaparkan bundel ke konfigurasi tingkat aplikasi. Hal ini juga memudahkan orang lain atau diri kita sendiri untuk mengetahui cara mengonfigurasi bundel di masa mendatang dengan melihat konfigurasi yang diizinkan.
Daripada mengatur parameter secara langsung, kita dapat mengatur template sebagai bagian dari konfigurasi bundel. Beginilah cara bundel dalam kerangka menangani konfigurasinya. Langkah pertama adalah memberi tahu suite untuk mengharapkan konfigurasi yang terkait dengan templat dalam kategori Konfigurasi di direktori DependencyInjection. Ini secara otomatis dihasilkan jika Anda membuat bundel menggunakan perintah konsol generate:bundle:
root('acme');
$rootNode
->children()
->arrayNode('templates')
->useAttributeAsKey('name')
->isRequired()
->requiresAtleastOneElement()
->prototype('scalar')->end()
->end()
->end()
;
return $treeBuilder;
}
}
Di sini kita mengatakan kita menginginkan satu set templat, sejauh ini yang kita katakan adalah templat itu harus ada dan harus memiliki setidaknya satu elemen. Kami sekarang tidak dapat menjalankan aplikasi karena terjadi pengecualian karena persyaratan ini tidak terpenuhi.
Kami sekarang dapat menambahkannya ke config.yml
file, alih-alih bagian parameter, kami menambahkannya ke bagian dengan kunci tingkat atas yang cocok dengan nama paket yang disetel sebagai nama simpul akar dalam kategori konfigurasi di atas. Misalnya, ini adalah “acme”:
# app/config/config.yml
acme:
templates:
full: "::full-layout.html.twig"
partial: "::partial-layout.html.twig"
Pada titik ini kita dapat menghapus pengaturan sebelumnya dari nilai-nilai ini di bagian parameter konfigurasi.
Sekarang kita seharusnya dapat memuat aplikasi tanpa pengecualian konfigurasi, tetapi nilai template belum ditetapkan sebagai parameter. Untuk ini kita juga perlu mengambil konfigurasi yang telah terbukti dan mengatur parameternya secara langsung. Ini dilakukan dalam kategori Extension di folder DependencyInjection, yang juga dibuat secara otomatis. Kita dapat melihat konfigurasi sedang diproses di dua baris pertama metode load. Ini adalah lokasi profilnya, misalnya config.yml
Dan config_dev.yml
Gabungkan dan validasi terhadap pohon dalam kategori konfigurasi.
Kita dapat menggunakan array konfigurasi yang diproses untuk mengakses nilai dan menetapkannya sebagai parameter:
processConfiguration($configuration, $configs);
$container->setParameter('acme.templates', $config['templates']);
$loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');
}
}
Kini kita kembali ke titik awal dan harus melakukan beberapa perubahan untuk mencapainya, jadi apa yang sebenarnya kita peroleh? Sejauh ini, ekstensi Twig kami masih mengharapkan kunci tertentu disetel dalam larik tersebut, yang akan menimbulkan masalah jika kunci tersebut hilang. Kita dapat mulai mengambil manfaat dari perubahan ini dengan memperkuat pengaturan otentikasi dalam kategori konfigurasi.
Dalam hal ini, kami tidak hanya menginginkan array berisi nilai tertentu, kami ingin menyetel kunci tertentu. Jadi, untuk memastikan bahwa kunci “penuh” dan “sebagian” memiliki nilai, kita dapat mengubah konfigurasinya menjadi:
//...
$rootNode
->children()
->arrayNode('templates')
->isRequired()
->children()
->scalarNode('main')->isRequired()->end()
->scalarNode('partial')->isRequired()->end()
->end()
->end()
->end()
;
//...
Jika kami biasanya menggunakan nama yang sama untuk templat ini, maka kami dapat menetapkan nilai default dan menggunakan konvensi untuk menghindari konfigurasi eksplisit, namun tetap mempertahankan kemungkinan untuk mengganti nilai jika kami perlu:
//...
$rootNode
->children()
->arrayNode('templates')
->addDefaultsIfNotSet()
->children()
->scalarNode('main')
->defaultValue('::full-layout.html.twig')
->end()
->scalarNode('partial')
->defaultValue('::partial-layout.html.twig')
->end()
->end()
->end()
->end()
;
//...
Ada perintah konsol untuk membuang konfigurasi, menampilkan kunci yang tersedia dan nilai preset apa pun. Ini dibuang sebagai Yaml, sehingga Anda dapat menyalinnya sebagai pint awal paket konfigurasi Anda. Anda dapat menjalankannya untuk paket demo ini app/console config:dump-reference acme
.
Kita dapat menambahkan informasi tambahan dari pohon konfigurasi menggunakan perintah berikut info()
Dan example()
metode. Informasi dicetak sebagai komentar di atas tombol yang ditugaskan padanya; contoh dicetak sebagai komentar sebaris setelah nilainya. Contoh ini tidak terlalu berguna jika kita sudah memiliki default, jadi mari kita kembali ke versi tanpa default dan menyempurnakannya dengan beberapa informasi tambahan:
//...
$rootNode
->children()
->arrayNode('templates')->info('The names of the parent templates to use')
->isRequired()
->children()
->scalarNode('main')
->isRequired()
->example('::full-layout.html.twig')
->end()
->scalarNode('partial')
->isRequired()
->example('::partial-layout.html.twig')
->end()
->end()
->end()
->end()
;
//...
Sekarang menjalankan perintah konsol memberi kita:
Default configuration for extension with alias: "acme"
acme:
# The parent templates to use
templates:
main: ~ # Required, Example: ::full-layout.html.twig
partial: ~ # Required, Example: ::partial-layout.html.twig
Oleh karena itu, kami membuat paket kami lebih tangguh dengan memvalidasi konfigurasinya dan memberikan lebih banyak informasi tentang konfigurasi ini untuk penggunaan di masa mendatang. Ada lebih banyak opsi yang tersedia saat memvalidasi konfigurasi karena ada lebih banyak kemungkinan persyaratan seputar konfigurasi yang diperlukan. Dokumentasi resmi memiliki lebih banyak informasi tentang kemungkinan ketika menentukan konfigurasi.