Làm cách nào để đưa một XHTML khác vào XHTML bằng Facelets JSF 2.0?


218

Cách chính xác nhất để đưa một trang XHTML khác vào trang XHTML là gì? Tôi đã thử nhiều cách khác nhau, không ai trong số họ đang làm việc.

Câu trả lời:


423

<ui:include>

Cách cơ bản nhất là <ui:include>. Các nội dung bao gồm phải được đặt bên trong <ui:composition>.

Ví dụ khởi động của trang chính /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>

Trang bao gồm /WEB-INF/include.xhtml(có, đây là toàn bộ tệp, mọi thẻ bên ngoài <ui:composition>đều không cần thiết vì dù sao chúng cũng bị Facelets bỏ qua):

<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>
  

Điều này cần phải được mở bằng /page.xhtml. Do lưu ý rằng bạn không cần phải lặp lại <html>, <h:head><h:body>bên trong bao gồm tập tin mà nếu không sẽ cho kết quả không hợp lệ HTML .

Bạn có thể sử dụng biểu thức EL động trong <ui:include src>. Xem thêm Làm thế nào để ajax-refresh động bao gồm nội dung bằng menu điều hướng? (JSF SPA) .


<ui:define>/<ui:insert>

Một cách tiên tiến hơn bao gồm là templating . Điều này bao gồm về cơ bản các cách khác. Trang mẫu chính nên sử dụng <ui:insert>để khai báo các vị trí để chèn nội dung mẫu được xác định. Trang khách mẫu đang sử dụng trang mẫu chính sẽ sử dụng <ui:define>để xác định nội dung mẫu sẽ được chèn.

Trang mẫu chính /WEB-INF/template.xhtml(như một gợi ý thiết kế: đầu trang, menu và chân trang có thể lần lượt là <ui:include>các tệp):

<!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>

Trang khách hàng mẫu /page.xhtml(lưu ý templatethuộc tính; cũng ở đây, đây là toàn bộ tệp):

<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>

Điều này cần phải được mở bằng /page.xhtml. Nếu không có <ui:define>, thì nội dung mặc định bên trong <ui:insert>sẽ được hiển thị thay thế, nếu có.


<ui:param>

Bạn có thể truyền tham số cho <ui:include>hoặc <ui:composition template>bằng <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 >

Trong tệp bao gồm / mẫu, nó sẽ có sẵn dưới dạng #{foo}. Trong trường hợp bạn cần truyền "nhiều" tham số <ui:include>, thì tốt hơn hết bạn nên xem xét việc đăng ký tệp đính kèm dưới dạng tagfile, để cuối cùng bạn có thể sử dụng nó như vậy <my:tagname foo="#{bean.foo}">. Xem thêm Khi nào nên sử dụng <ui: include>, tệp thẻ, thành phần hỗn hợp và / hoặc thành phần tùy chỉnh?

Bạn thậm chí có thể vượt qua toàn bộ đậu, phương thức và tham số thông qua <ui:param>. Xem thêm JSF 2: làm thế nào để vượt qua một hành động bao gồm một đối số được gọi đến chế độ xem phụ Facelets (sử dụng ui: include và ui: param)?


Gợi ý thiết kế

Các tệp không được phép truy cập công khai chỉ bằng cách nhập / đoán URL của nó, cần được đặt trong /WEB-INFthư mục, như tệp bao gồm và tệp mẫu trong ví dụ trên. Xem thêm Tôi cần đặt tập tin XHTML nào vào / WEB-INF và tập tin nào không?

Không cần phải có bất kỳ đánh dấu (mã HTML) nào bên ngoài <ui:composition><ui:define>. Bạn có thể đặt bất kỳ, nhưng chúng sẽ bị bỏ qua bởi Facelets. Đưa đánh dấu vào đó chỉ hữu ích cho các nhà thiết kế web. Xem thêm Có cách nào để chạy một trang JSF mà không cần xây dựng toàn bộ dự án không?

Loại tài liệu HTML5 là loại tài liệu được đề xuất hiện nay, "mặc dù" đó là tệp XHTML. Bạn sẽ thấy XHTML như một ngôn ngữ cho phép bạn tạo đầu ra HTML bằng công cụ dựa trên XML. Xem thêm Có thể sử dụng JSF + Facelets với HTML 4/5 không? JavaServer Faces 2.2 và HTML5 hỗ trợ, tại sao XHTML vẫn được sử dụng .

Các tệp CSS / JS / hình ảnh có thể được bao gồm dưới dạng tài nguyên có thể di chuyển / cục bộ / phiên bản động. Xem thêm Làm thế nào để tham khảo tài nguyên CSS / JS / hình ảnh trong mẫu Facelets?

Bạn có thể đặt các tệp Facelets trong tệp JAR có thể sử dụng lại. Xem thêm Cấu trúc cho nhiều dự án JSF với mã được chia sẻ .

Để biết các ví dụ trong thế giới thực về việc tạo khuôn mặt Facelets nâng cao, hãy kiểm tra src/main/webappthư mục của mã nguồn Java EE Kickoff AppOmniFaces hiển thị mã nguồn trang web .


1
Xin chào Balus, về: Cách cơ bản nhất là <ui: bao gồm>. Nội dung bao gồm phải được đặt bên trong <ui: bố cục>. Tôi nghĩ rằng nội dung được bao gồm có thể chỉ đơn giản là trong <p> </ p> nó sẽ hoạt động.
Koray Tugay

1
@KorayTugay: Vâng, đúng rồi. ui: thành phần chỉ cần thiết để a) sử dụng một mẫu (xem ở trên) hoặc b) để bọc mọi thứ trong <html> <body> để bạn có thể tải tệp bằng trình duyệt hoặc trình soạn thảo HTML.
sleske

Hi bạn có thể vui lòng giải câu đố này cho tôi? Tôi đã đập đầu từ 3 ngày qua. stackoverflow.com/questions/24738079/ cường
Kishor Prakash

1
@Odysseus: không phải nếu nó thực sự là một sáng tác.
BalusC

1
Afaik nếu chỉ khai báo <ui:composition ...>bên trong facelet, bạn cũng phải khai báo loại tài liệu giống như vậy <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">, nếu không, bạn sẽ entity referenced but not declaredgặp lỗi khi sử dụng các thực thể HTML.
ChristophS

24

Trang bao gồm:

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

Bao gồm trang:

<!--the inclusion line in the including page with the content-->
<ui:include src="yourFile.xhtml"/>
  • Bạn bắt đầu tập tin xhtml bao gồm của bạn ui:compositionnhư được hiển thị ở trên.
  • Bạn bao gồm tệp đó ui:includetrong tệp xhtml bao gồm như được hiển thị ở trên.

Đôi khi nó không đủ để xác định đường dẫn trong khi bạn chỉ sử dụng tên tệp. Đối với những người đã thử bao gồm tập tin ở trên và nó không hoạt động. Bạn có thể thử thêm biểu tượng dấu gạch chéo trước tên tệp hoặc thư mục WEB-INF. Vì vậy, nó trông giống như <ui:include src="/yourFile.xhtml"/>hoặc<ui:include src="/WEB-INF/yourFile.xhtml"/>
Lefan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.