使用 Joomla 5 中的 ModalSelect 表單欄位類型,可以在開發擴充功能時使用類別、製造商和搜尋在模式視窗中進行過濾,從而簡化從數千個產品中找到正確產品的流程。
簡介
在與客戶合作的過程中,會遇到各種程度的任務:有人需要一個 5-6 頁的簡單網站。有人需要大量的商品目錄或使用 REST API 與第三方系統整合的線上商店。其他人需要非標準功能,但沒有可用的流行解決方案。
Joomla 非常適合開發,並允許您創建易於維護的程式碼。如果需求遵循 CMS 核心,那麼它對所有這些情況都有答案。
要完成一個大項目,我們需要將其拆分為更小的任務,我想在本文中討論解決其中一個任務。
初始數據
客戶已經在 Joomla (JoomShopping) 線上商店的熱門組件之一上建立了產品目錄。他們可以選擇產品的參數,將其放入購物車並進行購買。一切如常。但是,現在您需要新增為產品建立圖形佈局的功能。例如,您的產品是杯子或 T 卹。在購買之前,您可以去找產品設計師,上傳您的徽標或照片,編寫文本,然後將此佈局附加到線上商店的訂單中。付款後,佈局直接進入生產,圖像和文字將被應用到您的杯子上並發送到地址。
由於此功能的實作非常耗時,因此將其建立為單獨的產品設計器元件。並且資料提供者外掛程式已經創建,允許您使用一個或另一個電子商務元件。
其中一個小的應用任務是在線上商店組件的商品和產品設計器組件中的商品之間建立連接。對於將來處理內容的內容管理者來說,這應該是方便且直覺的。因此,僅建立一個文字欄位來指示所需產品的 ID 號碼是不夠的。一個網路商店可能只有幾十種產品,那麼選擇一款產品來溝通並不是一件很困難的事。如果有數千種產品,則按參數搜尋和過濾產品的功能就很重要。如果您可以按類別、製造商過濾產品列表,或按名稱在數百個其他產品中尋找產品,您的工作將變得更快、更輕鬆。
看影片
此欄位與編輯器按鈕插件(editors-xtd 群組)的工作非常相似,其中用於選擇的資料顯示在模式視窗中:文章的連結、模組的簡短程式碼等。
一點理論
在Joomla管理員面板中,有不同的欄位需要填入其他元件的資料:指定文章、選單項目、聯絡人、產品等。通常這些欄位被設計為選擇選項下拉列表,它們可以設計為帶有資料列表的輸入類型=“文字”,但也有方便的欄位顯示所需實體的列表,具有過濾、搜尋和分頁功能。不僅網站內的來源(各種元件、外掛程式)可以充當資料來源,還可以透過 REST API 提供第三方服務:CRM、交付服務、外部資料庫、其他 Joomla 網站等等。
當在選單項目中選擇文章(例如「文章- 單篇文章」、「聯絡人- 單一聯絡人」)或建立選單項目的別名- 「系統連結- 選單」時,我們都看過這些字段的作用項目別名」。不過,讓我們提醒自己它們是什麼樣子的。
模態文章選擇視窗。
模式單一聯絡人選擇視窗。
Joomla中模態選擇字段的機會
讓我們仔細看看這些欄位 - 它們到底允許您做什麼。在內心深處,我們知道該欄位的主要工作是取得所選實體的ID並將該ID放入文字段落。但在螢幕上我們看到了其他東西 - 我們看到的不是 ID 號,而是文章或聯絡人的標題。很好很方便。您不需要記住 ID 為 1452704 的文章的名稱。此外,影片清楚顯示,如果該欄位已經有值,則會出現「清除」按鈕。它會重置欄位的值並允許您再次點擊“選擇”按鈕。
在某些情況下,我們有機會在建立選單項目的過程中建立選定類型的實體 - 文章、聯絡人等
。此按鈕的工作原理考慮了 ACL - Joomla 中的存取權限分離。假設您正在建立一個網站並建立一個「聯絡人」頁面。如果您沒有一堆結構複雜的公司分支機構,那麼這只是「未分類」類別中常見的 Joomla 文章。它已經擁有文本或變數形式的所有聯絡人。在古代,您必須先建立文章,然後轉到選單項目並為其建立選單項目。你現在不必這樣做。
如果欄位已經有值,那麼在某些情況下,可以在建立選單項目的過程中編輯所選實體(文章、選單項目等)。
因此,使用模式視窗中的選擇字段,我們可以:
- 選擇
- 建立
- 編輯
- 清晰
這就是我眼前的情況。但在 Joomla 的深處還有一個奇怪的 urlCheckin 參數,它允許您將選定的值傳送到欄位中指定的 url。值得注意的是,Joomla 中的這項功能已經逐漸發展了相當長的時間。然而,可以滿足您的需求的單獨通用欄位類型僅出現在 Joomla 5 中。甚至在 Joomla 4 中也沒有。
Joomla管理面板介面的Form建構函式的欄位是如何排列的?
以前,這個建構子稱為 JForm。我假設並非所有讀者都擁有像 IDE 這樣的開發工具 - 開發環境 - PHP Storm 或 VS Code,因此我將嘗試提供額外的指導來導航程式碼庫。
在 Joomla 中,邏輯與視圖(實際的 HTML 輸出)是分離的,因此我們將同時在多個地方對其進行探索。
邏輯是表單類
邏輯是表單類別。在 Joomla 5 中,Form 類別檔案位於 libraries/src/Form 中。我們檢查這些文件是為了了解邏輯本身、資料會發生什麼以及如何使用它。
簡而言之,Form 建構子接收帶有欄位描述的 XML。讀取資料(欄位類型、來自 addfieldprefix 屬性的自訂欄位類別(如果有)等),使用 FormHelper 載入所需的欄位類別。如果字段有一些過濾輸出資料的規則 - 使用 FormRule 類別 - 記住 filelist 類型的 Joomla 字段,您可以在其中指定過濾參數並選擇,例如僅 php 或僅 css 檔案。
Joomla 表單欄位類別檔案 位於libraries/src/Form/Field。溫和地說,有很多。這是管理面板的建造材料,有時也是前端的建造材料。
類別檔案描述了類別屬性,例如 $type、$layout 以及其他操作所需的屬性。大多數字段都有方法 getInput() - 實際上返回字段的 HTML 輸出,getLayoutData() - 在將字段發送到渲染之前預處理字段數據,getLabel() - 使用字段標籤等。
我們記得欄位類別繼承父 FormField 類別。在類別檔案 libraries/src/Form/FormField.php 中,描述了欄位的可能屬性,這些屬性可以在 XML 描述中使用。他們簡要地描述了它是什麼以及為什麼。
子類別(繼承者)能夠使用父類別的方法,並在必要時覆寫它。
Joomla 5 中字段的視圖(HTML 輸出、佈局)
每個欄位類別都有一個 HTML 輸出。在經典的 MVC 中,視圖會立即處理資料輸出,但在 Joomla 中還有一個附加層 - 佈局,它允許您覆蓋佈局 - 該 CMS 最重要的功能之一。 核心佈局是預計位於站點根目錄的 layouts 資料夾 中。它們傳遞一個 $displayData 數組,其中包含從 getLayoutData() 方法接收到的所有資料。我們在 $layout 類別屬性中指定要使用的輸出佈局。
<?php /** * Name of the layout being used to render the field * * @var string * @since 3.7 */ protected $layout = 'joomla.form.field.email';
這種類型的錄音很常見。在 Joomla 中,layout 是網站根目錄下的佈局資料夾中佈局檔案的以點分隔的路徑。 也就是說,條目 $layout = 'joomla.form.field.email' 表示渲染欄位時將使用版面配置 layouts/joomla/form/field/email.php.
<?php use Joomla\CMS\Layout\LayoutHelper; $displayData = [ 'src' => $this->item->image, 'alt' => $this->item->name, ]; echo LayoutHelper::render( 'joomla.html.image', $displayData );
同樣,此範例將使用佈局layouts/joomla/html/image.php。可以在網站範本和管理面板的 html 資料夾中覆蓋某些版面配置。
因此,如果我們想確切地看到最終有哪些資料進入佈局以及如何顯示,請轉到佈局檔案中查看。
在 Joomla 5 的模態選擇視窗中建立資料選擇字段
現在讓我們回到本文的主要任務。
範例對於我們學習很重要(撰寫本文時為 Joomla 5.0.1):
- 此欄位的主類別是libraries/src/Form/Field/ModalSelectField.php
- Joomla 文章模態選擇欄位 - administrator/components/com_content/src/Field/Modal/ArticleField.php
- 選單類型模態選擇欄位 - administrator/components/com_menus/src/Field/MenutypeField.php
- 選單項目模態選擇欄位 - administrator/components/com_menus/src/Field/MenutypeField.php
- 輸出佈局 - layouts/joomla/form/field/modal-select.php
在撰寫本文時,com_contacts 中的單一聯絡人模式選擇欄位尚未轉換為通用欄位類型一,僅位於(在撰寫本文時的Joomla 5.0.2 中)administrator /components/com_contact/src/ Field/Modal/ContactField.php。它直接繼承FormField,而不是ModalSelectField。
加入自己的欄位的操作演算法如下:
- 使用 xml 檔案中的欄位或以程式設計方式使用 SimpleXMLElement 建立 XML 表單。
- 如果我們即時工作,則使用 onContentPrepareForm 事件的插件,將 XML 表單新增至所需的表單(在此之前檢查 $form->getName())
- 建立欄位類別。
- 如有必要,我們可以建立自己的欄位 HTML 輸出(佈局)。我們將把它排除在本文的討論範圍之外。 它有效。 ## 欄位 XML 這段程式碼中最重要的是 addfieldprefix 屬性,它的意思是字段類別的命名空間。類別名稱由 addfieldprefix "" type "Field" 組成。在這種情況下,欄位類別將為 JoomlaPluginWtproductbuilderProviderjoomshoppingFieldProductlistField。
<?php /** * Name of the layout being used to render the field * * @var string * @since 3.7 */ protected $layout = 'joomla.form.field.email';
字段的 HTML 輸出(佈局)
為了清楚 PHP 中發生的一切,您需要先查看欄位輸出的佈局。它位於檔案 layouts/joomla/form/field/modal-select.php 中。事實上,有 2 個輸入欄位是輸出 - 一個可見,另一個不可見。所選文章、聯絡人或產品的標題以佔位符的形式輸入到可見欄位 - $valueTitle 參數。第二個是他的 id - $value。如果我們還沒有選擇任何內容,則該欄位中應該有一個短語,例如「選擇文章」或「選擇產品」。這是一個語言常數,我們將其放入 XML 欄位的提示屬性中或欄位類別的 setup() 方法中。
可用於輸出佈局的所有參數(這表示可以透過程式設計方式或在 XML 檔案中使用的參數):
<?php /** * Name of the layout being used to render the field * * @var string * @since 3.7 */ protected $layout = 'joomla.form.field.email';
PHP 字段類
正如您可能已經猜到的那樣,字段類別位於我的插件中。方法plugins/wtproductbuilder/providerjoomshopping/src/Field/ProductlistField.php。我以單模態文章選擇欄位為基礎,重新設計它以滿足我的需求——從 JoomShopping 線上商店選擇產品。我們用我們自己的類別來擴展父 ModalSelectField 類別。
我的任務只包括產品選擇,編輯和創作不是,所以在文章正文中我們只討論產品選擇。 PHP類別很小,我會完整給出並評論。
<?php use Joomla\CMS\Layout\LayoutHelper; $displayData = [ 'src' => $this->item->image, 'alt' => $this->item->name, ]; echo LayoutHelper::render( 'joomla.html.image', $displayData );
另外,引入了 getValueTitle() 方法,該方法在已選擇並保存實體的情況下顯示所選實體的名稱(產品名稱、文章標題等)。也就是說,我們去編輯選單項,我們不觸及該字段,但我們希望看到人們可以理解的文章標題/產品名稱,而不僅僅是一個id。此方法顯示所需的標題。
<field type="productlist" name="product_id" addfieldprefix="Joomla\Plugin\Wtproductbuilder\Providerjoomshopping\Field" label="Field label" hint="Field placeholder"></field>
在一些需要更複雜功能的欄位中 - 多語言關聯等 - 欄位類別中還有其他方法覆寫 FormField 類別的基本方法:
- setLayoutData() 是在實際渲染欄位之前預處理資料的方法
- getRenderer() - 用於渲染的附加參數 等等
在我們的例子中,沒有這樣的需求,所以我們不使用它們。
模態視窗內容的 HTML 輸出
按一下「選擇」按鈕時,將開啟一個模式 Bootstrap 窗口,其中在
在我的外掛程式中,onAjaxProviderjoomshopping() 方法傳回產品清單的 HTML 輸出。我們用它們循環遍歷數組,拍攝照片、名稱和輸出。程式碼通常很長,所以我將發布最重要的片段。
簡化循環程式碼範例:
<?php extract($displayData); /** * Layout variables * ----------------- * @var string $autocomplete Autocomplete attribute for the field. * @var boolean $autofocus Is autofocus enabled? * @var string $class Classes for the input. * @var string $description Description of the field. * @var boolean $disabled Is this field disabled? * @var string $group Group the field belongs to. <fields> section in form XML. * @var boolean $hidden Is this field hidden in the form? * @var string $hint Placeholder for the field. * @var string $id DOM id of the field. * @var string $label Label of the field. * @var string $labelclass Classes to apply to the label. * @var boolean $multiple Does this field support multiple values? * @var string $name Name of the input field. * @var string $onchange Onchange attribute for the field. * @var string $onclick Onclick attribute for the field. * @var string $pattern Pattern (Reg Ex) of value of the form field. * @var boolean $readonly Is this field read only? * @var boolean $repeat Allows extensions to duplicate elements. * @var boolean $required Is this field required? * @var integer $size Size attribute of the input. * @var boolean $spellcheck Spellcheck state for the form field. * @var string $validate Validation rules to apply. * @var string $value Value attribute of the field. * @var string $dataAttribute Miscellaneous data attributes preprocessed for HTML output * @var array $dataAttributes Miscellaneous data attribute for eg, data-* * @var string $valueTitle * @var array $canDo * @var string[] $urls * @var string[] $modalTitles * @var string[] $buttonIcons */
第二個。連結標籤代碼必須包含我們需要的資料的資料屬性。我們在貨物輸出循環的範例程式碼中看到了這個片段。
<?php /** * Name of the layout being used to render the field * * @var string * @since 3.7 */ protected $layout = 'joomla.form.field.email';
JavaScript 處理。將資料從 發送到父視窗中的字段
現在讓我們開始使用 JavaScript。在撰寫本文的過程中,出現了一些細微差別,使我們能夠討論新舊工作方式。
我們記得在工作的過程中,我們連接了以下js腳本
- media/system/js/fields/modal-fields.min.js - 此檔案已連接到文章選擇欄位的類別。然而,我們現在可以說這是一種古老且過時的工作方法。不再需要該文件。我們在 PHP 類別中註解掉了它。
- media/plg_wtproductbuilder_providerjoomshopping/js/providerjoomshopping.modal.js - 我們自己的 js 檔案。
讓我們從自己的 javascript 開始。在這裡,使用 select-link 類,我們獲取所有選擇器並將單擊事件的偵聽器掛在它們上。
<?php use Joomla\CMS\Layout\LayoutHelper; $displayData = [ 'src' => $this->item->image, 'alt' => $this->item->name, ]; echo LayoutHelper::render( 'joomla.html.image', $displayData );
如果 id 和 title 一切都很直觀,那麼資料物件和 postMessage 對於那些習慣使用 Joomla 的人來說可能並不明顯。
就像在 Joomla 3 和 Joomla 4 中一樣
之前,在Joomla 2.5、3.x 甚至4.x 中,使用了以下方法:在字段輸出的佈局中,我們使用內聯腳本將處理函數掛在視窗上,並從< ;iframe>我們稱為window.parent[functionName]。看看這段程式碼
<field type="productlist" name="product_id" addfieldprefix="Joomla\Plugin\Wtproductbuilder\Providerjoomshopping\Field" label="Field label" hint="Field placeholder"></field>
在此形式中,函數名稱在文章/聯絡人/選單項目清單中每個連結的 data-function 屬性中指定。函數本身被內聯放置,有時將其名稱與附加 id 統一。例如,"jSelectArticle_".$this->id.
jSelectArticle() 函數或類似函數(我們將使用 jSelectProduct())是檔案 modal-fields.min.js 中標準 processModalSelect() 函數的包裝器。它依序呼叫 processModalParent() 函數並在執行後關閉模態視窗。
這個函數需要指定一堆參數才能運作:實體的類型(文章、聯絡人等)、欄位的前綴(實際上是 HTML 欄位選擇器的 id)、實際的 id和 title - 我們需要的參數等
在一項功能中,所有場合的一切都被收集起來。這就是我們欄位中資料的放置位置。
Joomla 5 中的情況如何
但是,現在,在 Joomla 5 中,不再需要此文件。如果我們使用欄位輸出的標準佈局,那麼 modal-content-select-field 資源就會連接到它,以一種新的方式運作。
現在,Joomla 5 前端正在切換為使用 JavaScript postMessages。由於並非所有舊擴充都已準備好切換到新 Rails,因此已實作 JoomlaExpectingPostMessage 標誌,它允許您區分過時的事件呼叫方法。它與所描述的工作方法有間接關係,但可能對某人有用。在完全過渡到 postMessages 後,此標誌將被刪除。
所以,現在我們不需要帶有被呼叫函數名稱的額外連結屬性。相反,我們使用 postMessage 機制。為此,在資料物件中,我們需要指定等於 joomla:content-select 的 messageType 參數。為什麼?從 JavaScript 的角度來看,在 Joomla 中工作如下:
- 點擊連結並取得連結屬性
- 向父視窗發送訊息 window.parent.postMessage(data)
- media/system/js/fields/modal-content-select-field.js 檔案連接到具有訊息事件監聽器的父視窗。
- 它檢查訊息類型,如果是 joomla:content-select,則將值放置在必填欄位中並關閉模式視窗
在研究Joomla核心程式碼和尋找解決方案的過程中,很自然地遇到了jSelectArticle()之類的函數。然後我遇到了 postMessage 並決定透過給它一個長的唯一名稱來創建我的 MessageType。為了使其工作,我編寫了自己的處理過程,調用(事實證明,已經過時的)processModalSelect() 函數。我面臨的事實是,儘管資料已正確插入到欄位中,但模式視窗不想以任何方式關閉。進一步的搜尋首先找到了正確的事件類型,然後刪除了不必要的腳本並簡化了整個程式碼。
概括
Joomla 為開發人員提供了一套豐富的工具,用於處理第三方來源的資料並從第三方來源獲取資料並在程式碼中使用它。對於開發人員建立自己的擴充功能時,使用 JForm 欄位非常重要,特別是當需要解決超出典型範圍的任務時。當然,這樣的模式視窗和其中的資料選擇是一種相當特殊的情況,但透過這種方式,您既可以覆蓋任何其他 JForm 字段,也可以使用自己的 UX 邏輯創建自己的類型。
Joomla 社群資源
- https://joomla.org/
- Joomla 社區雜誌中的這篇文章
以上是在 Joomla 中使用模態選擇範例建立自訂表單欄位類型的詳細內容。更多資訊請關注PHP中文網其他相關文章!

PHPSession失效的原因包括配置錯誤、Cookie問題和Session過期。 1.配置錯誤:檢查並設置正確的session.save_path。 2.Cookie問題:確保Cookie設置正確。 3.Session過期:調整session.gc_maxlifetime值以延長會話時間。

在PHP中調試會話問題的方法包括:1.檢查會話是否正確啟動;2.驗證會話ID的傳遞;3.檢查會話數據的存儲和讀取;4.查看服務器配置。通過輸出會話ID和數據、查看會話文件內容等方法,可以有效診斷和解決會話相關的問題。

多次調用session_start()會導致警告信息和可能的數據覆蓋。 1)PHP會發出警告,提示session已啟動。 2)可能導致session數據意外覆蓋。 3)使用session_status()檢查session狀態,避免重複調用。

在PHP中配置會話生命週期可以通過設置session.gc_maxlifetime和session.cookie_lifetime來實現。 1)session.gc_maxlifetime控制服務器端會話數據的存活時間,2)session.cookie_lifetime控制客戶端cookie的生命週期,設置為0時cookie在瀏覽器關閉時過期。

使用數據庫存儲會話的主要優勢包括持久性、可擴展性和安全性。 1.持久性:即使服務器重啟,會話數據也能保持不變。 2.可擴展性:適用於分佈式系統,確保會話數據在多服務器間同步。 3.安全性:數據庫提供加密存儲,保護敏感信息。

在PHP中實現自定義會話處理可以通過實現SessionHandlerInterface接口來完成。具體步驟包括:1)創建實現SessionHandlerInterface的類,如CustomSessionHandler;2)重寫接口中的方法(如open,close,read,write,destroy,gc)來定義會話數據的生命週期和存儲方式;3)在PHP腳本中註冊自定義會話處理器並啟動會話。這樣可以將數據存儲在MySQL、Redis等介質中,提升性能、安全性和可擴展性。

SessionID是網絡應用程序中用來跟踪用戶會話狀態的機制。 1.它是一個隨機生成的字符串,用於在用戶與服務器之間的多次交互中保持用戶的身份信息。 2.服務器生成並通過cookie或URL參數發送給客戶端,幫助在用戶的多次請求中識別和關聯這些請求。 3.生成通常使用隨機算法保證唯一性和不可預測性。 4.在實際開發中,可以使用內存數據庫如Redis來存儲session數據,提升性能和安全性。

在無狀態環境如API中管理會話可以通過使用JWT或cookies來實現。 1.JWT適合無狀態和可擴展性,但大數據時體積大。 2.Cookies更傳統且易實現,但需謹慎配置以確保安全性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

記事本++7.3.1
好用且免費的程式碼編輯器

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器