Friday Dec 14, 2007
Friday Dec 14, 2007
If you have installed the NetBeans IDE support for Ruby and you are interested in integrating jMaki in your Ruby on Rails projects, here is a five-minute tutorial that will get you started. In this tutorial, you add a Yahoo data table to a Ruby on Rails view. (If you have not yet installed the NetBeans IDE 6.0 or if you need to add Ruby support to your NetBeans IDE, learn how to here.)
<%= jmaki_widget 'yahoo.dataTable',
:value =>
{:columns => [
{ :label => 'Id', :id => 'id'},
{ :label =>'Type', :id => 'type'},
{ :label => 'Price', :id => 'price'},
],
:rows => @items
}
-%>
|
Wednesday Sep 26, 2007
The jMaki 1.0 framework, with support for Java, PHP, and Ruby, was released yesterday. Last week, Arun Gupta posted a screencast showing how to use jMaki wrappers of button and table widgets from Dojo and Yahoo frameworks in a Ruby on Rails application built using the NetBeans 6.0 Beta IDE.
With Arun's permission, I am supplying the steps to recreate a similar jMaki on Rails project. To save steps, I changed the order a bit. If you don't already have NetBeans Ruby Support, go to the Installing and Configuring Ruby Support tutorial for instructions.
mysqladmin -u root -p create rorjmakitables_developmentIf you don't need a password, omit the -p.
development: adapter: mysql database: rorjmakitables_development username: root password: root_password host: localhost
map.connect '', :controller => 'say', :action=>'table'
<%= jmaki_widget 'yahoo.button',
:value => { :label => 'Select 1',
:action => { :topic => '/jmaki/table/select',
:message => { :targetId => '1' }
}
} -%>
<%= jmaki_widget 'yahoo.button',
:value => { :label => 'Select 2',
:action => { :topic => '/jmaki/table/select',
:message => { :targetId => '2' }
}
} -%>
These buttons use the jMaki publish/subscribe mechanism to publish to the /jmaki/table/select topic, which you will program two table widgets to listen to. The table widgets will select either the first row or the second row, depending on which button is clicked. For more details on how to use publish/subscribe, see Carla Mott's Widgets Talking To Widgets blog entry.
<%= jmaki_widget 'yahoo.dataTable', :subscribe=> "/jmaki/table",
:value =>
{:columns => [
{ :label => 'Title', :id => 'title'},
{ :label => 'Author', :id => 'author'},
{ :label => 'ISBN', :id => 'isbn'},
{ :label => 'Description', :id => 'description'}
],
:rows => [
{ :id=> '1', :title => 'Book Title 1',
:author => 'Author 1', :isbn => '4412',
:description => 'A Some long description'},
{ :id => '2', :title => 'Book Title 2',
:author => 'Author 2', :isbn => '4412',
:description => 'A Some long description'}
]
}
-%>
<%= jmaki_widget 'dojo.table', :subscribe=> "/jmaki/table",
:value =>
{:columns => [
{ :label => 'Title', :id => 'title'},
{ :label => 'Author', :id => 'author'},
{ :label => 'ISBN', :id => 'isbn'},
{ :label => 'Description', :id => 'description'}
],
:rows => [
{ :id=> '1', :title => 'Book Title 1',
:author => 'Author 1', :isbn => '4412',
:description => 'A Some long description'},
{ :id=> '2', :title => 'Book Title 2',
:author => 'Author 2', :isbn => '4412',
:description => 'A Some long description'}
]
}
-%>
class CreateGrids < ActiveRecord::Migration
def self.up
create_table :grids do |t|
t.column :title, :string
t.column :author, :string
t.column :isbn, :string
t.column :description, :string
end
Grid.create(:title=> 'Marathon',
:author=> 'Jeff Galloway',
:isbn=> '0936070250',
:description => 'A running book for everybody');
Grid.create(:title=> 'The Runners Bible',
:author=> 'Marc Bloom',
:isbn=> '0385188749',
:description => 'How to train, race, and get in shape');
end
def self.down
drop_table :grids
end
end
class SayController < ApplicationController
def index
table
render :action => 'table'
end
def table
@rows_data = []
Grid.find_all().each do |data|
@rows_data << { :id => data.id,
:title => data.title,
:author => data.author,
:isbn => data.isbn,
:description => data.description
}
end
end
end
The above code defines the rows_data variable and initializes it to an empty array. It uses the active record to find all the rows from the database and, for each row, add a hash of the fields to the rows_data array.
<%= jmaki_widget 'dojo.table',
:value =>
{:columns => [
{ :label => 'Title', :id => 'title'},
{ :label =>'Author', :id => 'author'},
{ :label => 'ISBN', :id => 'isbn'},
{ :label => 'Description', :id => 'description'}
],
:rows => @rows_data
}
-%>
<%= jmaki_widget 'yahoo.dataTable',
:value =>
{:columns => [
{ :label => 'Title', :id => 'title'},
{ :label => 'Author', :id => 'author'},
{ :label => 'ISBN', :id => 'isbn'},
{ :label => 'Description', :id => 'description'}
],
:rows => @rows_data
}
-%>
There you have it! To learn more about jMaki, go to www.jmaki.com. To learn more about NetBeans support for Ruby, go to wiki.netbeans.org/wiki/view/Ruby.
Friday Aug 10, 2007
Yesterday, in our blog entry about using the Spry Accordion widget, we mentioned that it uses the same data model as the tabbed view and that you would swap out widgets. Today I will show you how simple it is to do so.
First, complete the steps from yesterday's mini-tutorial.
Next, open your Base jMaki project, and drag a Yahoo Tabbed View widget into index.jsp. Run the project to ensure that all the necessary files are copied into the resources/yahoo folder.
Copy the resources/yahoo folder from the Base jMaki project and paste it into the resources folder of your Visual Web project.
Click JSP to view the JSP tags for Page1. Replace the following line:
<a:widget name="spry.accordion" value="#{SessionBean1.tripContent}"/>
with:
<a:widget name="yahoo.tabbedview"
value="#{SessionBean1.tripContent}" />
Now click the Run Main Project button. You should see a tabbed view instead of the accordion.
Thursday Aug 09, 2007

The jMaki team keeps making great changes to the technology, but sometimes it is hard to keep up with all the changes. I have finally gotten a working version of the latest jMaki-wrapped Spry Accordion. I think that this API will be stable for awhile, so now is a good time to post some instructions on how to use the Spry Accordion in a NetBeans 5.5.1 Visual Web project using the latest NetBeans jMaki plug-in (1.6.9.9.9.5), which bundles jMaki 0.9.7.
One of the recent changes has been the data model. The jMaki team is now publishing the data model information on the ajax.dev.java.net portal at http://wiki.java.net/bin/view/Projects/jMakiDataModels. The data model for the Spry Accordion widget is as follows:
items::= "{" {<label> } "}"
label ::= "{" "label:" <string>, [<content> | <include> |<action> ]
[<lazyload>] [<rowid>] <selected>"},"
selected ::= "selected:" "true" | "false" (default is false)
include ::= "include:" <string> ,
lazyload ::= "lazyload:" "true" | "false",
rowid ::= "rowid:" <string> ,
content ::= "content:" <string>,
action ::= "action:" "{" [<topic>] <message> "},"
topic ::= "topic:" <string>,
message ::= "message:" <obj>
obj ::= <string> | <JavaScript object literal>
|
Note: This model is the same as the data model for the tabbed view. This means that you can swap out the accordion with a tabbed view and not have to change the data.
To follow this mini-tutorial, you need to get the NetBeans jMaki Plugin. If you have already installed the plugin, use the NetBeans Update Center from the Tools menu to make sure you have the latest version (1.6.9.9.9.5). If you have an earlier version, See Carla's blog entry about how to update the jMaki framework resources in a jMaki project.
I noted in an earlier blog entry that you also need to download the JSF Compounds library (jsfcompounds-0.0.2.jar). This is no longer true. The 1.6.9.9.9.5 plug-in includes this library.
BaseJSFjMaki/Web Pages/glue.js to Your-VWP-Project/Web Pages.
BaseJSFjMaki/Web Pages/resources to Your-VWP-Project/Web Pages/resources:
config.jsonjmaki.js
system-glue.js
BaseJSFjMaki/Web Pages/resources/spry folder to Your-VWP-Project/Web Pages/resources.
xmlns:a="http://jmaki/v1.0/jsf" to the <jsp:root> tag.
<webuijsf:panelGroup binding="#{Page1.groupPanel1}" id="groupPanel1"
style="position: absolute; left: 72px; top: 48px;">
<a:widget name="spry.accordion" value="#{SessionBean1.tripContent}"/>
</webuijsf:panelGroup> |
Now we can setup the web application to return data from the Travel database in the data model format for the accordion.
SELECT ALL TRAVEL.PERSON.PERSONID,
TRAVEL.PERSON.NAME,
TRAVEL.TRIP.TRIPID,
TRAVEL.TRIP.DEPDATE
FROM TRAVEL.PERSON
INNER JOIN TRAVEL.TRIP ON TRAVEL.TRIP.PERSONID =
TRAVEL.PERSON.PERSONID
ORDER BY TRAVEL.PERSON.PERSONID ASC,
TRAVEL.TRIP.DEPDATE ASC
|
public String getTripContent() {
// Data Model Format
// { items : [
// {label: "label", content : "content"},
// ...
// ]}
String retVal = "";
try {
retVal = buildTripTreeData().toString();
} catch (JSONException ex) {
log("Exception building tree data" +
ex.getMessage());
}
return retVal;
}
public JSONObject buildTripTreeData()
throws JSONException {
JSONObject rootObject = new JSONObject();
JSONArray items = new JSONArray();
JSONObject itemObject = new JSONObject();
boolean hasNext = tripDataProvider.cursorFirst();
Integer currentPersonId =
(Integer) tripDataProvider.getValue(
"PERSON.PERSONID");
String currentName =
tripDataProvider.getValue(
"PERSON.NAME").toString();
StringBuffer currentContent = new StringBuffer();
while (hasNext) {
Integer newPersonId =
(Integer) tripDataProvider.getValue(
"PERSON.PERSONID");
if (!newPersonId.equals(currentPersonId)) {
// write out data for previous person
itemObject.put("label", currentName);
itemObject.put("content",
currentContent.toString());
items.put(itemObject);
// start gathering data for a new item
currentPersonId = newPersonId;
currentName =
tripDataProvider.getValue(
"PERSON.NAME").toString();
itemObject = new JSONObject();
currentContent = new StringBuffer();
}
// Add trip's date to the content
currentContent.append(tripDataProvider.getValue(
"TRIP.DEPDATE").toString() +
"<br>");
hasNext = tripDataProvider.cursorNext();
}
// write out data for last person
itemObject.put("label", currentName);
itemObject.put("content", currentContent.toString());
items.put(itemObject);
rootObject.put("items", items);
return rootObject;
}
|
Greg and Carla say that they have added some cool features to the accordion widget. I am hoping that as I learn about them, I can add to this mini-tutorial.
Thursday Jun 14, 2007
We have been blogging about jMaki for over a year, and, during that time, the technology has gone through many iterations, making most of our posts obsolete. With the release of 9.3, there became enough changes that it was time to start reposting these mini tutorials. So, to start, here are new instructions for adding jMaki to a Visual Web Application project or a Sun Java Studio Creator project.
Note: To learn about the modifications, see Carla Mott's Big changes in jMaki blog entry.
Aug 6, 2007 Update: With the later versions, such as 9.6.1, they abstracted some of the functionalities into a separate JSF Compounds library ( jsfcompounds-0.0.2.jar), which you can download from https://ajax.dev.java.net/servlets/ProjectDocumentList?folderID=7871. You must add this jar file to your classpath, by right-clicking the Libraries node in the Projects window, choosing Add Jar/Folder, navigating to and selecting jsfcompounds-0.0.2.jar, and clicking Open. A symptom of this missing jar file is getting the following error in the JSP editor: java.lang.NoClassDefFoundError: com/truchsess/faces/compound/webapp/CompoundChildTagBase
/widgets for the desired
widget libraries. In this mini tutorial, you will use the Tree widget from
the Yahoo widget library, so, at a minimum, unzip the jmaki-yahoo
zip so that you end up with jmaki-dir/widgets/resources/yahoo./scripts/glue.js to project-dir/web.
/scripts/system-glue.js and jmaki-dir/scripts/jmaki.js
to project-dir/web/resources. /core/web/resources/config.json to
project-dir/web/resources. /lib/ajax-wrapper-comp.jar,
and click OK. /widgets/resources.
For this mini tutorial, you need to copy jmaki-dir/widgets/resources/yahoo
to project-dir/web/resources.xmlns:a="http://jmaki/v1.0/jsf" to the <jsp:root>
tag. Now you are done setting up your project resources and you can add the Tree
widget to your web page. One problem that you have to work around is that the
jMaki widgets do not expose their features using the Design-Time
API. What this means is that you will not be able to see the widgets in
the Visual Designer. In addtion, with jMaki, you wrap the component in an <a:widget>
tag. Even if you were to use a component from the Pallette, if you wrap the
component in an <a:widget> tag, the Visual Designer won't
see it. To make it easier to work with the widgets in the Visual Designer, I
usually put them inside layout components, such as the Grid Panel. That way,
I can position the widgets and be able to see in the Visual Designer where the
jMaki widgets are on the page.
Note: Work is in progress to provide the jMaki widgets in component libraries that will work in the Visual Designer. We did a JavaOne Hands-On Lab that covered how this is done.
border property
to 1 to make it easier to visualize the location of the widget
on the page. You can clear the border property when you are ready
to deploy.
<h:panelGrid binding="#{Page1.gridPanel1}" border="1" id="gridPanel1"
style="position: absolute; left: 48px; top: 48px">
<a:widget name="yahoo.tree"
value="{'root' : {
'title' : 'Food',
'expanded' : true,
'children' : [
{'title' : 'Nuts'},
{'title' : 'Fruit',
'children' : [
{'title' : 'Banana'}
]
}
]
}
}"/>
</h:panelGrid> |
<ui:script binding="#{Page1.script1}" id="script1">
var handler = function(message) {
alert('You selected ' + message.value.label);
}
jmaki.subscribe("/yahoo/tree/onClick", handler);
</ui:script> |
<webuijsf:script binding="#{Page1.script1}" id="script1">
var handler = function(message) {
alert('You selected ' + message.value.label);
}
jmaki.subscribe("/yahoo/tree/onClick", handler);
</webuijsf:script> |
Wednesday Apr 11, 2007
For the past few months, I have been collaborating with a great group of people to bring you a fantastic hands on lab for JavaOne. This lab, session # LAB-4460 Building Ajax-Enabled JavaServer Faces Components and Web Applications With jMaki, Dynamic Faces, and the NetBeans IDE, was put together by Craig McClanahan, Matthew Bohm, Gail and Paul Anderson, Winston Prakash, and myself. It starts out by showing how to use Dynamic Faces (JSF Extensions) to add Ajax functionality to plain old JavaServer Faces components. It then teaches you how to build your own JSF Ajax-enabled component and add design-time features so that you can use it in the NetBeans Visual Web Pack. Last, it shows how to build a JSF component from a jMaki widget. By leveraging an existing jMaki widget and specialized base classes, you quickly build an Ajax-enabled JavaServer Faces component offering a rich user interface with a minimum of code.
They will also be handing out CDs of the hands on labs. The CDs contain additional labs including another lab (4420) that Craig, Matt, and I wrote that covers some of the above material as well as how to use the jMaki-wrapped DHTML Goodies Tooltip widget. In addition, the CD contains lab 4450. I contributed a section to this lab that shows how to use the jMaki-wrapped Dojo Fisheye widget.
Wednesday Sep 06, 2006
Note: See Using jMaki 9.3 With the NetBeans Visual Web Pack or the Sun Java Studio Creator IDE for updated instructions on how to add jMaki to a project.
Jennifer Ball just published two new jMaki tutorials, which you can read about in her blog. One of the tutorials shows how to use jMaki in JavaServer Faces projects, and it completes the information that I needed to figure out how to integrate a jMaki widget in a page built using the Java Studio Creator IDE. In particular, how to bind to a bean property, how to save off the widget's values, and how to make managed bean methods available for the AJAX requests.
So, here is a mini-tutorial on how to use jMaki to add a dojo AJAX combo box to a JavaServer Faces web page.
jar xvf jMaki.war
command, or you can rename the file to have a .zip extension and unzip it.jmaki/resources/jmaki.js to creator-project-dir/web/resources.
jmaki/resources/dojo/combobox to creator-project-dir/web/resources/dojo/combobox.
/resources/libs/dojo directory
(not the whole dojo directory) to creator-project-dir/web/resources/libs/dojo/version.3.1.
jmaki/WEB-INF/lib/ajax-wrapper-comp.jar to creator-project-dir/web/WEB-INF/lib.
ajax-wraper-comp.jar
to the IDE's library manager. Then, you can easily add the jMaki library to
a project by right-clicking the Libraries node in the Projects window and
choosing Add Library. xmlns:a="http://java.sun.com/jmaki-jsf" to the top-level
<div> tag. a:ajax tag inside an f:verbatim
tag, as shown below. Note that the service attribute is referring to
ApplicationBean1. Later, you add the completeCountry() method
to the application bean to return the list of choices.value="#{ApplicationBean1.completeCountry}".
Once I get it figured out, I will post a new entry.
<?xml version="1.0" encoding="UTF-8"?>
<jsp:root version="1.2" xmlns:a="http://java.sun.com/jmaki-jsf"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:ui="http://www.sun.com/web/ui">
<jsp:directive.page contentType="text/html;charset=UTF-8"
pageEncoding="UTF-8"/>
<f:view>
<ui:page binding="#{Page1.page1}" id="page1">
<ui:html binding="#{Page1.html1}" id="html1">
<ui:head binding="#{Page1.head1}" id="head1">
<ui:link binding="#{Page1.link1}" id="link1"
url="/resources/stylesheet.css"/>
</ui:head>
<ui:body binding="#{Page1.body1}" id="body1"
style="-rave-layout: grid">
<ui:form binding="#{Page1.form1}" id="form1">
<ui:panelGroup binding="#{Page1.groupPanel1}"
id="groupPanel1"
style="position: absolute; left: 24px; top: 48px">
<f:verbatim>
<a:ajax id="cb1" name="dojo.combobox"
service="ApplicationBean1-completeCountry.ajax" />
</f:verbatim>
</ui:panelGroup>
</ui:form>
</ui:body>
</ui:html>
</ui:page>
</f:view>
</jsp:root>
|
AbstractApplicationBean and use
the Managed Beans node in the Projects window to make the class' properties
available in application scope.
private String[] countries =new String[] {
"Canada", "France", "Uganda", "Ukraine", "United States of America",
"United Kingdom", "Japan", "Korea", "Jamacia", "Thailand"
};
private String[] countryCodes =
new String[] {"CA", "FR", "UG", "UR", "USA", "UK", "JP",
"KR", "JA", "TH"
};
public void completeCountry(FacesContext context,
String[] args,AjaxResult result) {
result.setResponseType(AjaxResult.JSON);
result.append("[");
for (int loop=0; loop < countries.length; loop++){
result.append("[\"" + countries[loop] + "\",\""
+ countryCodes[loop] + "\" ]");
if (loop < countries.length -1) result.append(",");}
result.append("]");
}
|
private String country = "";
public String getCountry() {
return country;
}
public void setCountry(String country){
this.country = country;
}
|
value="#{SessionBean1.country}"
attribute to the ajax tag, as shown below.
<a:ajax id="cb1" name="dojo.combobox"
service="ApplicationBean1-completeCountry.ajax"
value="#{SessionBean1.country}"/>
|
onSubmit property
to jmaki.attributes.get('form1:cb1').saveState();.Go.Back.
Click the ... button for the component's url property, choose
Page1, and click OK.value attribute is bound
to the session bean's country property, the previously selected value is displayed.
To understand how the jMaki tags work, I highly recommend that you read both of Jennifer's tutorials.
Thursday Aug 03, 2006
Note: See Using jMaki 9.3 With the NetBeans Visual Web Pack or the Sun Java Studio Creator IDE for updated instructions on how to add jMaki to a project.
One of the widgets in the jMaki zip is the Spry Accordion. I thought this would be a nice way to display a page fragment menu in an application that I am building using the Sun Java Studio Creator IDE. Here is how I used the jMaki tag library to add the Accordion widget to my page fragment.
1. First, I downloaded the latest jMaki zip from https://ajax.dev.java.net/. I used 3.2.6.
2. Just like with my earlier project, I unjared the jar file and copied the necessary files to my project:
jmaki/resources/jmaki.js to creator-project-dir/web/resources.
jmaki/WEB-INF/types.properties to creator-project-dir/web/WEB-INF.
jmaki/WEB-INF/lib/ajax-wrapper-comp.jar to creator-project-dir/web/WEB-INF/lib.
jmaki/resources/spry/plainAccordion to creator-project-dir/web/resources/spry/plainAccordion.
3. Additionally, I added a resources/libs directory and copied over
the Spry libraries from jmaki/resources/libs/spry.
4. I added a pageFragment, Sidebar.jspf, to my project, and in the JSP file for
my page fragment, I added xmlns:a="http://java.sun.com/jmaki" to
the top-level <div> tag.
5. In the page fragment, I used a Group Panel component to wrap the jMaki tag.
The JSPF file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<div style="height: 400px; width: 200px; -rave-layout: grid"
xmlns:a="http://java.sun.com/jmaki"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://www.sun.com/web/ui">
<f:subview id="Sidebar">
<ui:panelGroup binding="#{Sidebar.groupPanel1}"
id="groupPanel1"
style="height: 382px; left: 0px; top: 0px; position: absolute; width: 190px">
<f:verbatim>
<a:ajax type="spry" name="spry.plainAccordion" />
</f:verbatim>
</ui:panelGroup>
</f:subview>
</div>
|
6. I wanted each section in the accordion to resize to the section's content.
The samples that you get when you download the components from Adobe come with
an AquaAccordion style that does not set a section height. To save some time,
I simply copied those styles to the resources/spry/accordion/components.css
file.
.AquaAccordion {
border-left: solid 1px gray;
border-right: solid 1px black;
border-bottom: solid 1px gray;
overflow: hidden;
font-family: "Times New Roman", Times, serif;
font-size: 16px;
}
.AquaAccordion .Tab {
height: 24px;
background-image: url(images/aqua-gradient.gif);
background-repeat: repeat-x;
background-color: #6dc1fc;
border-top: solid 1px black;
border-bottom: solid 1px gray;
margin: 0px;
padding: 2px;
cursor: pointer;
-moz-user-select: none;
-khtml-user-select: none;
text-align: center;
}
.AquaAccordion .Content {
overflow: auto;
margin: 0px;
padding: 0px;
background-image: url(images/gray-gradient.gif);
background-repeat: repeat-x;
}
.AquaAccordion .hover {
background-image: none;
background-color: #33CCFF;
}
|
7. Now I can design my Accordion widget menu. In this simple example, I hard-coded
the menu contents in my resources/spry/accordion/components.htm
file. Note that because I am using the overriding styles, I am using Panel instead
of AccordionPanel, Tab instead of AccordionPanelTab, and so forth.
<div id="${uuid}" class="AquaAccordion" tabindex="0">
<div class="Panel">
<div class="Tab">
<div class="Label">Fruit</div>
</div>
<div class="Content">
<a href="faces/FoodDetail.jsp?name=banana">Banana</a><br/>
<a href="faces/FoodDetail.jsp?name=papaya">Papaya</a><br/>
<a href="faces/FoodDetail.jsp?name=grapes">Grapes</a><br/>
</div>
</div>
<div class="Panel">
<div class="Tab">
<div class="Label">Vegetables</div>
</div>
<div class="Content">
<a href="faces/FoodDetail.jsp?name=avocado">Avocado</a><br/>
<a href="faces/FoodDetail.jsp?name=sprouts">Brussel Sprouts</a><br/>
<a href="faces/FoodDetail.jsp?name=asparagus">Asparagus</a><br/>
<a href="faces/FoodDetail.jsp?name=onion">Onion</a><br/>
</div>
</div>
<div class="Panel">
<div class="Tab">
<div class="Label">Grains and Cereal</div>
</div>
<div class="Content">
<a href="faces/FoodDetail.jsp?name=rice">Rice</a><br/>
<a href="faces/FoodDetail.jsp?name=macaroni">Macaroni</a><br/>
</div>
</div>
</div>
|
8. To make the content sections shrink to fit the content, you must turn off
animation, so I modified the widget creation statement in component.js as follows:
var acc1 = new Spry.Widget.Accordion(widget.uuid, { enableAnimation: false });
9. I can now add this page fragment to all the pages in my application.