Bagaimana cara memasukkan XHTML lain dalam XHTML menggunakan JSF 2.0 Facelets?

218

Apa cara paling benar untuk memasukkan halaman XHTML lain ke halaman XHTML? Saya telah mencoba berbagai cara, tidak ada yang bekerja.

Ikthiander
sumber

Jawaban:

423

<ui:include>

Cara paling mendasar adalah <ui:include>. Konten yang disertakan harus ditempatkan di dalam <ui:composition>.

Contoh awal halaman master /page.xhtml:

<!DOCTYPE html>
<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <h:head>
        <title>Include demo</title>
    </h:head>
    <h:body>
        <h1>Master page</h1>
        <p>Master page blah blah lorem ipsum</p>
        <ui:include src="/WEB-INF/include.xhtml" />
    </h:body>
</html>

Halaman include /WEB-INF/include.xhtml(ya, ini adalah keseluruhan file, semua tag di luar <ui:composition>tidak perlu karena diabaikan oleh Facelets):

<ui:composition 
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <h2>Include page</h2>
    <p>Include page blah blah lorem ipsum</p>
</ui:composition>
  

Ini perlu dibuka oleh /page.xhtml. Harap perhatikan bahwa Anda tidak perlu mengulang <html>, <h:head>dan <h:body>di dalam file sertakan seperti itu akan menghasilkan HTML yang tidak valid .

Anda dapat menggunakan ekspresi EL dinamis di <ui:include src>. Lihat juga Bagaimana ajax-menyegarkan dinamis termasuk konten dengan menu navigasi? (JSF SPA) .


<ui:define>/<ui:insert>

Cara yang lebih maju termasuk adalah templating . Ini pada dasarnya termasuk sebaliknya. Halaman templat induk harus digunakan <ui:insert>untuk mendeklarasikan tempat untuk memasukkan konten templat yang ditentukan. Halaman klien template yang menggunakan halaman template master harus digunakan <ui:define>untuk menentukan konten template yang akan dimasukkan.

Halaman templat induk /WEB-INF/template.xhtml(sebagai petunjuk desain: header, menu, dan footer pada gilirannya dapat berupa <ui:include>file):

<!DOCTYPE html>
<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
    <h:head>
        <title><ui:insert name="title">Default title</ui:insert></title>
    </h:head>
    <h:body>
        <div id="header">Header</div>
        <div id="menu">Menu</div>
        <div id="content"><ui:insert name="content">Default content</ui:insert></div>
        <div id="footer">Footer</div>
    </h:body>
</html>

Templat halaman klien /page.xhtml(perhatikan templateatributnya; juga di sini, ini adalah file secara keseluruhan):

<ui:composition template="/WEB-INF/template.xhtml"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

    <ui:define name="title">
        New page title here
    </ui:define>

    <ui:define name="content">
        <h1>New content here</h1>
        <p>Blah blah</p>
    </ui:define>
</ui:composition>

Ini perlu dibuka oleh /page.xhtml. Jika tidak ada <ui:define>, maka konten default di dalamnya <ui:insert>akan ditampilkan, jika ada.


<ui:param>

Anda dapat meneruskan parameter ke <ui:include>atau <ui:composition template>oleh <ui:param>.

<ui:include ...>
    <ui:param name="foo" value="#{bean.foo}" />
</ui:include>
<ui:composition template="...">
    <ui:param name="foo" value="#{bean.foo}" />
    ...
</ui:composition >

Di dalam file include / templat, file akan tersedia sebagai #{foo}. Jika Anda perlu mengirimkan parameter "banyak" <ui:include>, maka sebaiknya Anda mendaftarkan file sertakan sebagai tagfile, sehingga Anda akhirnya dapat menggunakannya seperti itu <my:tagname foo="#{bean.foo}">. Lihat juga Kapan menggunakan <ui: include>, menandai file, komponen komposit, dan / atau komponen khusus?

Anda bahkan dapat mengirimkan biji utuh, metode, dan parameter melalui <ui:param>. Lihat juga JSF 2: bagaimana cara meloloskan suatu tindakan termasuk argumen untuk dipanggil ke sub tampilan Facelet (menggunakan ui: include dan ui: param)?


Petunjuk desain

File-file yang seharusnya tidak dapat diakses publik dengan hanya memasukkan / menebak URL-nya, perlu ditempatkan di /WEB-INFfolder, seperti file sertakan dan file template dalam contoh di atas. Lihat juga File XHTML mana yang harus saya masukkan / WEB-INF dan yang tidak?

Tidak perlu ada markup (kode HTML) di luar <ui:composition>dan <ui:define>. Anda bisa memasukkan apa saja, tetapi mereka akan diabaikan oleh Facelet. Menempatkan markup di sana hanya berguna untuk desainer web. Lihat juga Apakah ada cara untuk menjalankan halaman JSF tanpa membangun keseluruhan proyek?

DOCTYPE HTML5 adalah DOCTYPE yang direkomendasikan hari ini, "terlepas dari" bahwa itu adalah file XHTML. Anda harus melihat XHTML sebagai bahasa yang memungkinkan Anda menghasilkan output HTML menggunakan alat berbasis XML. Lihat juga Apakah mungkin menggunakan JSF + Facelets dengan HTML 4/5? dan dukungan JavaServer Faces 2.2 dan HTML5, mengapa XHTML masih digunakan .

File CSS / JS / gambar dapat dimasukkan sebagai sumber daya relocatable / localized / versioned yang dinamis. Lihat juga Bagaimana referensi CSS / JS / sumber daya gambar dalam template Facelets?

Anda dapat meletakkan file Facelets dalam file JAR yang dapat digunakan kembali. Lihat juga Struktur untuk beberapa proyek JSF dengan kode bersama .

Untuk contoh nyata Templat Facelet tingkat lanjut, periksa src/main/webappfolder kode sumber Aplikasi Java EE Kickoff dan OmniFaces menampilkan kode sumber situs .

BalusC
sumber
1
Hai Balus, mengenai: Cara paling dasar adalah <ui: include>. Konten yang disertakan harus ditempatkan di dalam <ui: komposisi>. Saya kira konten yang disertakan dapat dengan mudah di <p> ​​</p> itu akan berfungsi.
Koray Tugay
1
@ KorayTugay: Ya, itu benar. ui: komposisi hanya diperlukan untuk a) menggunakan templat (lihat di atas), atau b) untuk membungkus semuanya dalam <html> <body> sehingga Anda dapat memuat file dengan browser atau editor HTML.
sleske
Hai, bisakah Anda menyelesaikan teka-teki ini untuk saya? Saya telah membenturkan kepala saya dari 3 hari terakhir. stackoverflow.com/questions/24738079/…
Kishor Prakash
1
@Odysseus: tidak jika itu sebenarnya komposisi.
BalusC
1
Afaik jika hanya menyatakan <ui:composition ...>di dalam facelet Anda harus mendeklarasikan doctype seperti <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">juga, jika tidak, Anda mendapatkan entity referenced but not declaredkesalahan saat menggunakan entitas HTML.
ChristophS
24

Halaman yang disertakan:

<!-- opening and closing tags of included page -->
<ui:composition ...>
</ui:composition>

Termasuk halaman:

<!--the inclusion line in the including page with the content-->
<ui:include src="yourFile.xhtml"/>
  • Anda memulai file xhtml Anda yang disertakan dengan ui:compositionseperti yang ditunjukkan di atas.
  • Anda menyertakan file itu dengan ui:includemenyertakan file xhtml seperti juga ditunjukkan di atas.
Benchik
sumber
Terkadang tidak cukup untuk mengidentifikasi jalur saat Anda hanya menggunakan nama file. Bagi mereka, yang mencoba penyertaan file di atas dan tidak berhasil. Anda dapat mencoba menambahkan simbol garis miring sebelum nama file atau / WEB-INF direktori. Jadi sepertinya <ui:include src="/yourFile.xhtml"/>atau<ui:include src="/WEB-INF/yourFile.xhtml"/>
Lefan