Jika Anda dapat hidup dengan mengganti semua batas autocomplete, Anda dapat mengganti layanan inti di Drupal 8;
Layanan yang Anda perlu timpa ada di sini di core.services.yml:
entity.autocomplete_matcher:
class: Drupal\Core\Entity\EntityAutocompleteMatcher
arguments: ['@plugin.manager.entity_reference_selection']
Di modul khusus Anda, tambahkan kelas yang mengimplementasikan ServiceModifierInterface
namespace Drupal\mymodule;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
class MyModuleServiceProvider implements ServiceModifierInterface {
/**
* Modifies existing service definitions.
*
* @param ContainerBuilder $container
* The ContainerBuilder whose service definitions can be altered.
*/
public function alter(ContainerBuilder $container) {
for ($id = 'entity.autocomplete_matcher'; $container->hasAlias($id); $id = (string) $container->getAlias($id));
$definition = $container->getDefinition($id);
$definition->setClass('Drupal\mymodule\Entity\EntityAutocompleteMatcherCustom');
$container->setDefinition($id, $definition);
}
}
Kemudian salin EntityAutocompleteMatcher.php ke modul Anda di /src/Entity/EntityAutocompleteMatcherCustom.php
Kemudian perbarui hardcoded 10 ke 50, atau batas apa pun yang Anda inginkan:
namespace Drupal\mymodule\Entity;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Tags;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface;
use Drupal\Core\Entity\EntityAutocompleteMatcher;
/**
* Matcher class to get autocompletion results for entity reference.
*/
class EntityAutocompleteMatcherCustom extends EntityAutocompleteMatcher {
/*
* {@inheritdoc]
*/
public function getMatches($target_type, $selection_handler, $selection_settings, $string = '') {
$matches = array();
$options = array(
'target_type' => $target_type,
'handler' => $selection_handler,
'handler_settings' => $selection_settings,
);
$handler = $this->selectionManager->getInstance($options);
if (isset($string)) {
// Get an array of matching entities.
$match_operator = !empty($selection_settings['match_operator']) ? $selection_settings['match_operator'] : 'CONTAINS';
// Changing limit from 10 to 50.
$entity_labels = $handler->getReferenceableEntities($string, $match_operator, 50);
// Loop through the entities and convert them into autocomplete output.
foreach ($entity_labels as $values) {
foreach ($values as $entity_id => $label) {
$key = "$label ($entity_id)";
// Strip things like starting/trailing white spaces, line breaks and
// tags.
$key = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(Html::decodeEntities(strip_tags($key)))));
// Names containing commas or quotes must be wrapped in quotes.
$key = Tags::encode($key);
$matches[] = array('value' => $key, 'label' => $label);
}
}
}
return $matches;
}
}
Jelas menimpa layanan inti memiliki beberapa risiko, tetapi itu keren bahwa Anda dapat melakukan ini.
Apa risiko mengungguli layanan inti?
1) Anda dapat kehilangan manfaat dari pembaruan saat Anda memperbarui inti. Jika ada perbaikan keamanan penting dalam layanan, dan salinan Anda yang diubah memiliki celah keamanan, Anda tidak akan mendapat manfaat dari komunitas yang memperbarui kode itu.
2) Modul lain yang Anda instal mungkin memiliki dependensi ke layanan asli dengan set fitur aslinya. Jadi misalkan ada beberapa kode dalam modul lain yang akan rusak jika jumlah entri autocomplete lebih besar dari atau kurang dari 10, Anda tidak akan mengetahuinya, sampai itu memengaruhi Anda.
3) Ini membuat basis kode Anda lebih sulit untuk dipelihara. Anda harus ingat bahwa Anda tidak menggunakan Drupal inti, tetapi versi yang diperpanjang. Pengembang lain yang bergabung dengan proyek Anda setelah Anda pergi mungkin mengalami kesulitan mencari tahu mengapa suatu layanan berperilaku dengan cara yang tidak standar.
Apakah ini inti peretasan?
Tergantung bagaimana Anda melihatnya. Itu tidak masuk ke modul inti dan mengubah kode. Bahkan tidak membuat tambalan dan menerapkannya dan melacaknya dengan manajer paket seperti komposer. Ini lebih dari satu kali penyesuaian yang mengubah perilaku inti situs, mirip dengan kait ALTER. Ini lebih mandiri daripada peretasan inti, karena itu ada dalam modul khusus Anda di situs Anda. Jadi, pembaruan inti ke layanan asli tidak akan terpengaruh, sama seperti jika Anda menambal atau meretas kode layanan asli.
Tetapi memang memiliki beberapa risiko yang sama dengan inti peretasan, seperti yang disebutkan di atas.
Dalam pertanyaan asli, masalah adalah judul node tidak cukup unik. Solusi yang lebih baik, selain mengubah batas drop-down secara global akan menyelesaikan masalah keunikan.
Apa yang saya sarankan adalah menambahkan field_display_title bidang baru dan menggunakannya pada halaman, dan jika Anda membutuhkannya field_teaser_title untuk ditampilkan pada halaman daftar di mana Anda memerlukan judul yang lebih pendek. Maka judul sebenarnya yang akan ditarik ke dropdown pilih referensi entitas dapat bermanfaat bagi editor Anda dan menjadi unik, seperti "Artikel Saya (halaman 1)" jika masalahnya adalah setiap halaman memiliki judul yang sama. Maka Anda tidak perlu mengganti layanan inti.
Ketika Anda menemukan masalah dengan Drupal, cobalah untuk menemukan solusi yang membutuhkan kode kustom paling sedikit. Ini membuat situs Anda lebih stabil, lebih mudah untuk memelihara dan menghemat waktu Anda.
Saya kira mengesampingkan EntityAutocompleteMatcher akan memengaruhi semua elemen formulir autocomplete di situs Anda. Jadi saya akan membuat plugin pemilihan entitas baru karena itu pendekatan yang lebih rinci. Plugin dapat diaktifkan per bidang. Ini adalah contoh dari plugin semacam itu. https://drupal.stackexchange.com/a/220136/433
Dalam kasus Anda, implementasi akan lebih sepele:
File: modules / example / src / Plugin / EntityReferenceSelection / ExampleSelection.php
Menggunakan NodeSelection sebagai kelas dasar alih-alih DefaultSelection akan memungkinkan Anda untuk memfilter node yang direferensikan berdasarkan statusnya. Perhatikan bahwa referensi tipe entitas lainnya belum didukung .
Tidak seperti widget tautan referensi entitas tidak memungkinkan untuk menentukan plugin pemilihan melalui antarmuka pengguna, karena itu Anda perlu mengaturnya secara terprogram menggunakan hook_field_widget_WIDGET_TYPE_form_alter () .
Adalah penting bahwa ID plugin berisi tanda titik koma.
sumber
Cara mudah lain untuk memodifikasi jumlah hasil adalah mengubah nilai rentang dalam kueri:
sumber
@Weri, saya akan menghindari melakukan itu, karena baru saja menerapkan saran Anda dan menghabiskan sebagian besar hari berusaha memperbaiki masalah lain.
Perubahan kueri yang Anda sarankan juga memengaruhi keseluruhan referensi saat menautkan paragraf ke node. Node yang saya bangun memiliki 80+ item paragraf sebelum saya menambahkan alter. Setelah ditambahkan, saya tidak dapat menyimpan simpul. Menghapus / Mengomentari alter memperbaiki masalah.
Memperbarui
Membungkus $ query-> range () dalam pemeriksaan rute memperbaiki masalah bagi saya, misalnya,
sumber
FWIW, Anda bisa mengatur tampilan formulir bidang menjadi "Pilih Daftar" daripada "Pelengkapan Otomatis".
Kemudian, Anda akan mendapatkan semua opsi, meskipun dalam format yang kurang nyaman, tetapi tidak diperlukan peretasan.
sumber