Author: hansbak
Date: Thu Apr 1 10:13:01 2010
New Revision: 929906
URL: http://svn.apache.org/viewvc?rev=929906&view=rev
Log:
Add ebayStoreCategory list (Categories from ebayStore seller ) in
'exportProduct to ebay' screen, The seller can export products from ofbiz to
ebay category and to their ebay store on ebay site.
Modified:
ofbiz/trunk/specialpurpose/ebaystore/servicedef/services.xml
ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayEvents.java
ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreOptions.java
ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreSiteFacade.java
ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/PrepareProductListing.groovy
ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/controller.xml
ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/store/productsearchExport.ftl
Modified: ofbiz/trunk/specialpurpose/ebaystore/servicedef/services.xml
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ebaystore/servicedef/services.xml?rev=929906&r1=929905&r2=929906&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ebaystore/servicedef/services.xml (original)
+++ ofbiz/trunk/specialpurpose/ebaystore/servicedef/services.xml Thu Apr 1
10:13:01 2010
@@ -381,13 +381,6 @@ under the License.
<attribute name="jobId" mode="IN" type="String" optional="false"/>
<attribute name="productStoreId" mode="IN" type="String"
optional="false"/>
</service>
- <service name="getEbayStoreCategories" engine="java"
transaction-timeout="3600"
- location="org.ofbiz.ebaystore.EbayStore"
invoke="getEbayStoreCategories" auth="true">
- <description>Get Ebay Store Category</description>
- <attribute name="productStoreId" type="String" mode="IN"
optional="false"></attribute>
- <attribute name="ebayStoreCategoryId" type="String" mode="IN"
optional="true"></attribute>
- <attribute name="storeCategories" type="List" mode="OUT"
optional="false"></attribute>
- </service>
<service name="autoBlockItemsOutOfStock" engine="java"
transaction-timeout="7200"
location="org.ofbiz.ebaystore.EbayStoreAutoPreferences"
invoke="autoBlockItemsOutOfStock" auth="false">
<description>Automatic service to send item dispatched notification
email when user mark sold listing as dispatched</description>
Modified:
ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayEvents.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayEvents.java?rev=929906&r1=929905&r2=929906&view=diff
==============================================================================
---
ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayEvents.java
(original)
+++
ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayEvents.java
Thu Apr 1 10:13:01 2010
@@ -64,6 +64,8 @@ import com.ebay.soap.eBLBaseComponents.R
import com.ebay.soap.eBLBaseComponents.ShippingServiceDetailsType;
import com.ebay.soap.eBLBaseComponents.ShippingTypeCodeType;
import com.ebay.soap.eBLBaseComponents.SiteCodeType;
+import com.ebay.soap.eBLBaseComponents.StoreCustomCategoryType;
+import com.ebay.soap.eBLBaseComponents.StorefrontType;
import com.ebay.soap.eBLBaseComponents.VATDetailsType;
import com.ebay.soap.eBLBaseComponents.WarningLevelCodeType;
import com.ebay.soap.eBLBaseComponents.ListingDesignerType;
@@ -414,6 +416,60 @@ public class EbayEvents {
return categories;
}
+ public static List<StoreCustomCategoryType>
getStoreChildCategories(HttpServletRequest request) throws ApiException,
SdkException, Exception {
+ List<StoreCustomCategoryType> categories = FastList.newInstance();
+ EbayStoreSiteFacade sf = null;
+ String categoryId = null;
+
+ if (UtilValidate.isEmpty(request.getParameter("productStoreId")) &&
UtilValidate.isEmpty(request.getAttribute("productStoreId"))) {
+ Debug.logError("Required productStoreId for get ebay
LeafCategories.", module);
+ return categories;
+ }
+ if (UtilValidate.isNotEmpty(request.getParameter("categoryId")) ||
UtilValidate.isNotEmpty(request.getAttribute("categoryId"))) {
+ categoryId = (String) request.getParameter("categoryId") != null ?
request.getParameter("categoryId") : (String)
request.getAttribute("categoryId");
+ Debug.logInfo("Load child categories from session following site
id and categoryId is ".concat(categoryId), module);
+ } else {
+ Debug.logWarning("No categoryId to get child categories.", module);
+ }
+
+ ApiContext apiContext = getApiContext(request);
+ sf = getSiteFacade(apiContext,request);
+ if (UtilValidate.isNotEmpty(sf)) {
+ Map<SiteCodeType, List<StoreCustomCategoryType>> csCateMaps =
sf.getSiteStoreCategoriesMap();
+ List<StoreCustomCategoryType> csCateList =
csCateMaps.get(apiContext.getSite());
+ if (UtilValidate.isNotEmpty(csCateList)) {
+ for (StoreCustomCategoryType csCate : csCateList) {
+ StoreCustomCategoryType[] categoryChildCategories =
csCate.getChildCategory();
+ if (categoryChildCategories.length > 0) {
+ for (StoreCustomCategoryType childCategory :
categoryChildCategories) {
+ StoreCustomCategoryType[] categoryChild2 =
childCategory.getChildCategory();
+ if (categoryChild2.length > 0) {
+ for (StoreCustomCategoryType categoryChild3 :
categoryChild2) {
+ categories.add(categoryChild3);
+ }
+ } else {
+ categories.add(childCategory);
+ }
+ }
+ } else {
+ categories.add(csCate);
+ }
+ }
+ //sort the cats list
+ Collections.sort(categories, new Comparator() {
+ public int compare(Object a, Object b) {
+ StoreCustomCategoryType cat1 =
(StoreCustomCategoryType) a;
+ StoreCustomCategoryType cat2 =
(StoreCustomCategoryType) b;
+ int catId1 =
Integer.parseInt(Long.toString(cat1.getCategoryID()));
+ int catId2 =
Integer.parseInt(Long.toString(cat2.getCategoryID()));
+ return catId1 - catId2;
+ }
+ });
+ }
+ }
+ return categories;
+ }
+
public static CategoryType getCsCategoriesMapped(HttpServletRequest
request) throws ApiException, SdkException, Exception{
EbayStoreSiteFacade sf = null;
String categoryId = null;
@@ -718,8 +774,18 @@ public class EbayEvents {
item.setPostalCode(requestParams.get("postalCode".concat(id)).toString());
attributeMapList.put("PostalCode",
requestParams.get("postalCode".concat(id)).toString());
}
+ StorefrontType storeFront = new StorefrontType();
+ if
(UtilValidate.isNotEmpty(requestParams.get("ebayStore1Category"))) {
+ storeFront.setStoreCategoryID(new
Long(requestParams.get("ebayStore1Category").toString()));
+ attributeMapList.put("StoreCategoryID",
requestParams.get("ebayStore1Category").toString());
+ }
+ if
(UtilValidate.isNotEmpty(requestParams.get("ebayStore2Category"))) {
+ storeFront.setStoreCategory2ID(new
Long(requestParams.get("ebayStore2Category").toString()));
+ attributeMapList.put("StoreCategory2ID",
requestParams.get("ebayStore2Category").toString());
+ }
+ item.setStorefront(storeFront);
addItemCall.setItem(item);
-
+
// create/update EbayProductListing entity
Map<String, Object> prodMap = FastMap.newInstance();
prodMap.put("productStoreId", productStoreId);
Modified:
ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreOptions.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreOptions.java?rev=929906&r1=929905&r2=929906&view=diff
==============================================================================
---
ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreOptions.java
(original)
+++
ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreOptions.java
Thu Apr 1 10:13:01 2010
@@ -55,6 +55,7 @@ import com.ebay.soap.eBLBaseComponents.G
import com.ebay.soap.eBLBaseComponents.GetStoreOptionsResponseType;
import com.ebay.soap.eBLBaseComponents.StoreColorSchemeType;
import com.ebay.soap.eBLBaseComponents.StoreColorType;
+import com.ebay.soap.eBLBaseComponents.StoreCustomCategoryType;
import com.ebay.soap.eBLBaseComponents.StoreFontFaceCodeType;
import com.ebay.soap.eBLBaseComponents.StoreFontSizeCodeType;
import com.ebay.soap.eBLBaseComponents.StoreFontType;
@@ -246,35 +247,6 @@ public class EbayStoreOptions {
return "success";
}
- public static String retrieveEbayStoreCategoryByParent(HttpServletRequest
request, HttpServletResponse response) {
- LocalDispatcher dispatcher = (LocalDispatcher)
request.getAttribute("dispatcher");
- HttpSession session = request.getSession();
- GenericValue userLogin = (GenericValue)
session.getAttribute("userLogin");
- Map<String,Object> result = FastMap.newInstance();
- Map<String,Object> context = FastMap.newInstance();
- try {
- Map paramMap = UtilHttp.getCombinedMap(request);
- if (paramMap.get("productStoreId") != null) {
- String ebayCategoryId = (String)paramMap.get("ebayCategoryId");
- context.put("productStoreId", paramMap.get("productStoreId"));
- context.put("ebayStoreCategoryId", ebayCategoryId);
- context.put("userLogin", userLogin);
- result = dispatcher.runSync("getEbayStoreCategories", context);
- if (result != null) {
- List<Map<String,Object>> categories =
(List<Map<String,Object>>) result.get("storeCategories");
- if (categories.size()>0) {
- toJsonObjectList(categories,response);
- }
- }
- }
- } catch (GenericServiceException e) {
- Debug.logError(e.getMessage(), module);
- } catch (EventHandlerException e) {
- Debug.logError(e.getMessage(), module);
- }
- return "success";
- }
-
public static void toJsonObjectList(List<Map<String,Object>> list,
HttpServletResponse response) throws EventHandlerException {
JSONObject json = null;
List<JSONObject> jsonList = new ArrayList<JSONObject>();
Modified:
ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreSiteFacade.java
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreSiteFacade.java?rev=929906&r1=929905&r2=929906&view=diff
==============================================================================
---
ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreSiteFacade.java
(original)
+++
ofbiz/trunk/specialpurpose/ebaystore/src/org/ofbiz/ebaystore/EbayStoreSiteFacade.java
Thu Apr 1 10:13:01 2010
@@ -28,6 +28,7 @@ import javolution.util.FastList;
import javolution.util.FastMap;
import org.ofbiz.base.util.Debug;
+import org.ofbiz.ebay.EbayHelper;
import org.ofbiz.entity.Delegator;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.ServiceUtil;
@@ -49,6 +50,7 @@ import com.ebay.sdk.attributes.model.ICa
import com.ebay.sdk.call.GetAttributesCSCall;
import com.ebay.sdk.call.GetCategory2CSCall;
import com.ebay.sdk.call.GetDescriptionTemplatesCall;
+import com.ebay.sdk.call.GetStoreCall;
import com.ebay.sdk.helper.cache.CategoriesDownloader;
import com.ebay.sdk.helper.cache.DetailsDownloader;
import com.ebay.sdk.helper.cache.FeaturesDownloader;
@@ -60,11 +62,16 @@ import com.ebay.soap.eBLBaseComponents.F
import com.ebay.soap.eBLBaseComponents.GetCategoryFeaturesResponseType;
import com.ebay.soap.eBLBaseComponents.GetDescriptionTemplatesRequestType;
import com.ebay.soap.eBLBaseComponents.GetDescriptionTemplatesResponseType;
+import com.ebay.soap.eBLBaseComponents.GetStoreRequestType;
+import com.ebay.soap.eBLBaseComponents.GetStoreResponseType;
import com.ebay.soap.eBLBaseComponents.GeteBayDetailsResponseType;
import com.ebay.soap.eBLBaseComponents.ItemSpecificsEnabledCodeType;
import com.ebay.soap.eBLBaseComponents.ItemSpecificsEnabledDefinitionType;
import com.ebay.soap.eBLBaseComponents.SiteCodeType;
import com.ebay.soap.eBLBaseComponents.SiteDefaultsType;
+import com.ebay.soap.eBLBaseComponents.StoreCustomCategoryArrayType;
+import com.ebay.soap.eBLBaseComponents.StoreCustomCategoryType;
+import com.ebay.soap.eBLBaseComponents.StoreType;
import com.ebay.soap.eBLBaseComponents.ThemeGroupType;
public class EbayStoreSiteFacade {
@@ -73,6 +80,7 @@ public class EbayStoreSiteFacade {
private IAttributesMaster attrMaster = null;
private static final int MAP_SIZE = 30000;
private Map<SiteCodeType, Map<String, CategoryType>> siteCategoriesMap =
new HashMap<SiteCodeType, Map<String, CategoryType>>();
+ private Map<SiteCodeType, List<StoreCustomCategoryType>>
siteStoreCategoriesMap = new HashMap<SiteCodeType,
List<StoreCustomCategoryType>>();
private Map<SiteCodeType, List<CategoryType>> siteCategoriesCSMap = new
HashMap<SiteCodeType,List<CategoryType>>();
private Map<SiteCodeType, Map<String, CategoryFeatureType>>
siteCategoriesFeaturesMap = new HashMap<SiteCodeType, Map<String,
CategoryFeatureType>>();
private Map<SiteCodeType, SiteDefaultsType> siteFeatureDefaultMap = new
HashMap<SiteCodeType, SiteDefaultsType>();
@@ -85,6 +93,7 @@ public class EbayStoreSiteFacade {
syncAllCategoriesFeatures();
syncEBayDetails();
getAllMergedCategories();
+ getEbayStoreCategories();
}
public static IAttributesXslProvider getDefaultStyleXsl() throws
java.io.IOException {
@@ -190,6 +199,34 @@ public class EbayStoreSiteFacade {
}
}
+ //get all categories from ebay store depend on siteId
+ private List<StoreCustomCategoryType> getEbayStoreCategories() {
+ Map<String, StoreCustomCategoryType> catsMap = new HashMap<String,
StoreCustomCategoryType>(30000);
+ List<StoreCustomCategoryType> catsList = FastList.newInstance();
+ try {
+ GetStoreCall call = new GetStoreCall(this.apiContext);
+ GetStoreRequestType req = new GetStoreRequestType();
+ GetStoreResponseType resp = null;
+ resp = (GetStoreResponseType) call.execute(req);
+ if (resp != null && "SUCCESS".equals(resp.getAck().toString())) {
+ StoreType store = resp.getStore();
+ StoreCustomCategoryArrayType categoriesArr =
store.getCustomCategories();
+ StoreCustomCategoryType[] cateogries =
categoriesArr.getCustomCategory();
+ for (StoreCustomCategoryType cat : cateogries) {
+ String categoryId = Long.toString(cat.getCategoryID());
+ catsMap.put(categoryId, cat);
+ }
+ for (StoreCustomCategoryType cat : catsMap.values()) {
+ catsList.add(cat);
+ }
+ siteStoreCategoriesMap.put(this.apiContext.getSite(),
catsList);
+ }
+ } catch (Exception e) {
+ return siteStoreCategoriesMap.get(this.apiContext.getSite());
+ }
+ return catsList;
+ }
+
public IAttributesMaster getAttrMaster() {
return attrMaster;
}
@@ -214,6 +251,10 @@ public class EbayStoreSiteFacade {
return siteCategoriesCSMap;
}
+ public Map<SiteCodeType, List<StoreCustomCategoryType>>
getSiteStoreCategoriesMap() {
+ return siteStoreCategoriesMap;
+ }
+
public Map<SiteCodeType, GeteBayDetailsResponseType> getEBayDetailsMap() {
return eBayDetailsMap;
}
Modified:
ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/PrepareProductListing.groovy
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/PrepareProductListing.groovy?rev=929906&r1=929905&r2=929906&view=diff
==============================================================================
---
ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/PrepareProductListing.groovy
(original)
+++
ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/actions/store/PrepareProductListing.groovy
Thu Apr 1 10:13:01 2010
@@ -89,14 +89,24 @@
}
// get category detail
pkCateId = null;
+ stCate1ID = null;
+ stCate2ID = null;
addItems.each{ addItemMap ->
addItem = addItemMap.addItemCall;
item = addItem.getItem();
if (productId == item.getSKU()) {
primaryCate = item.getPrimaryCategory();
+ storeFront = item.getStorefront();
+ if (storeFront) {
+ stCate1ID = storeFront.getStoreCategoryID();
+ stCate2ID = storeFront.getStoreCategory2ID();
+ context.storeFront = storeFront;
+ }
if (primaryCate) pkCateId = primaryCate.getCategoryID();
}
}
+ context.stCate1ID = stCate1ID;
+ context.stCate2ID = stCate2ID;
if (pkCateId) {
refName = "itemCateFacade_" + pkCateId;
if (addItemObj.get(refName)) {
Modified:
ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/controller.xml
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/controller.xml?rev=929906&r1=929905&r2=929906&view=diff
==============================================================================
---
ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/controller.xml
(original)
+++
ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/WEB-INF/controller.xml
Thu Apr 1 10:13:01 2010
@@ -274,6 +274,11 @@
<event type="java" path="org.ofbiz.ebaystore.EbayStoreOptions"
invoke="retrieveEbayCategoryByParent"/>
<response name="success" type="view" value="main"/>
</request-map>
+ <request-map uri="retrieveEbayStoreCategoryByParent">
+ <security https="true" auth="true"/>
+ <event type="java" path="org.ofbiz.ebaystore.EbayStoreOptions"
invoke="retrieveEbayStoreCategoryByParent"/>
+ <response name="success" type="view" value="main"/>
+ </request-map>
<request-map uri="clearExpListing">
<security https="true" auth="true"/>
<event type="java" path="org.ofbiz.ebaystore.EbayEvents"
invoke="clearProductListing"/>
@@ -310,23 +315,6 @@
<response name="error" type="view" value="exportProductListing"/>
</request-map>
- <!--request-map uri="prepareProductListingDetails">
- <security https="true" auth="true"/>
- <event type="java" path="org.ofbiz.ebaystore.EbayEvents"
invoke="prepareProductListingDetails"/>
- <response name="success" type="view" value="prepareProductListing"/>
- </request-map-->
- <!--request-map uri="retrieveEbayStoreCategoryByParent">
- <security https="true" auth="true"/>
- <event type="java" path="org.ofbiz.ebaystore.EbayStoreOptions"
invoke="retrieveEbayStoreCategoryByParent"/>
- <response name="success" type="view" value="main"/>
- </request-map-->
- <!--request-map uri="exportProductsFromEbayStore">
- <security https="true" auth="true"/>
- <event type="service-multi" invoke="exportProductsFromEbayStore"/>
- <response name="success" type="view" value="exportProductListing"/>
- <response name="error" type="view" value="exportProductListing"/>
- </request-map-->
-
<!-- Selling Manager -->
<request-map uri="sellingManager">
<security https="true" auth="true"/>
Modified:
ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/store/productsearchExport.ftl
URL:
http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/store/productsearchExport.ftl?rev=929906&r1=929905&r2=929906&view=diff
==============================================================================
---
ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/store/productsearchExport.ftl
(original)
+++
ofbiz/trunk/specialpurpose/ebaystore/webapp/ebaystore/store/productsearchExport.ftl
Thu Apr 1 10:13:01 2010
@@ -310,6 +310,72 @@ under the License.
</tr>
<!-- end of set category -->
<tr>
+ <td class="label">Store category
1</td>
+ <td>
+ <div>
+ <div id="loading"></div>
+ <select
id="ebayStore1Category" name="ebayStore1Category">
+ <option
value="">Please select</option>
+ <#if
storeCategories?exists>
+ <#if
storeFront?has_content>
+ <#if
!storeFront.isLeafCategory()?has_content>
+ <#assign
leafCate = "false">
+ <#else>
+ <#assign
leafCate = "true">
+ </#if>
+ <#assign
storeCate1Id = storeFront.getStoreCategoryID()?if_exists>
+ <option
selected value="${storeFront.getStoreCategoryID()?if_exists}"
>${storeFront.getStoreCategoryID()?if_exists}</option>
+ <#else>
+ <#list
storeCategories as csCate>
+ <#if
!csCate.IsLeafCategory?has_content>
+
<#assign leafCate = "false">
+ <#else>
+
CH_${storeFront.getStoreCategoryID()?if_exists}<#assign leafCate = "true">
+ </#if>
+ <#assign
categoryId = csCate.getCategoryID()?if_exists>
+ <option
value="${csCate.getCategoryID()?if_exists}"
>${csCate.getName()?if_exists}</option>
+ </#list>
+ </#if>
+ </#if>
+ </select>
+ </div>
+ <input type="hidden"
name="storeCate1Id" value="${storeCate1Id?if_exists}"/>
+ </td>
+ </tr>
+ <tr>
+ <td class="label">Store category
2</td>
+ <td>
+ <div>
+ <div id="loading"></div>
+ <select
id="ebayStore2Category" name="ebayStore2Category">
+ <option
value="">Please select</option>
+ <#if
storeCategories?exists>
+ <#if
storeFront?has_content>
+ <#if
!storeFront.isLeafCategory()?has_content>
+ <#assign
leafCate = "false">
+ <#else>
+ <#assign
leafCate = "true">
+ </#if>
+ <#assign
storeCate1Id = storeFront.getStoreCategoryID()?if_exists>
+ <option
selected value="${storeFront.getStoreCategoryID()?if_exists}"
>${storeFront.getStoreCategoryID()?if_exists}</option>
+ <#else>
+ <#list
storeCategories as csCate>
+ <#if
!csCate.IsLeafCategory?has_content>
+
<#assign leafCate = "false">
+ <#else>
+
CH_${storeFront.getStoreCategoryID()?if_exists}<#assign leafCate = "true">
+ </#if>
+ <#assign
categoryId = csCate.getCategoryID()?if_exists>
+ <option
value="${csCate.getCategoryID()?if_exists}"
>${csCate.getName()?if_exists}</option>
+ </#list>
+ </#if>
+ </#if>
+ </select>
+ </div>
+ <input type="hidden"
name="storeCate2Id" value="${storeCate1Id?if_exists}"/>
+ </td>
+ </tr>
+ <tr>
<td class="label">Title</td>
<td><input type="text" size="60"
name="title" value="${item.getTitle()?if_exists}"/></td>
</tr>