svn commit: r1222544 - in /ofbiz/trunk: applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ applications/order/webapp/ordermgr/entry/catalog/ applications/product/config/ applications/product/entitydef/ applications/product/script/org/ofb...

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r1222544 - in /ofbiz/trunk: applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ applications/order/webapp/ordermgr/entry/catalog/ applications/product/config/ applications/product/entitydef/ applications/product/script/org/ofb...

hansbak-2
Author: hansbak
Date: Fri Dec 23 03:49:11 2011
New Revision: 1222544

URL: http://svn.apache.org/viewvc?rev=1222544&view=rev
Log:
add the possibility of adding tags to products next to having keywords to products, can also optionally approve/reject via a status field

Added:
    ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/tagsearch.ftl   (with props)
Modified:
    ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy
    ofbiz/trunk/applications/product/config/ProductUiLabels.xml
    ofbiz/trunk/applications/product/entitydef/entitymodel.xml
    ofbiz/trunk/applications/product/entitydef/entitymodel_old.xml
    ofbiz/trunk/applications/product/script/org/ofbiz/product/UpgradeServices.xml
    ofbiz/trunk/applications/product/servicedef/services_upgrade.xml
    ofbiz/trunk/applications/product/src/org/ofbiz/product/product/KeywordIndex.java
    ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductEvents.java
    ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearch.java
    ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchSession.java
    ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml
    ofbiz/trunk/applications/product/widget/catalog/ProductForms.xml
    ofbiz/trunk/applications/product/widget/catalog/ProductScreens.xml
    ofbiz/trunk/framework/common/data/CommonTypeData.xml
    ofbiz/trunk/specialpurpose/ecommerce/config/EcommerceUiLabels.xml
    ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
    ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl
    ofbiz/trunk/specialpurpose/ecommerce/widget/CatalogScreens.xml

Modified: ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy (original)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/WEB-INF/actions/entry/catalog/ProductDetail.groovy Fri Dec 23 03:49:11 2011
@@ -662,4 +662,19 @@ if (product) {
     if("ASSET_USAGE".equals(productTypeId) || "ASSET_USAGE_OUT_IN".equals(productTypeId)){
         context.startDate = UtilDateTime.addDaysToTimestamp(UtilDateTime.nowTimestamp(), 1).toString().substring(0,10); // should be tomorrow.
     }
+    
+    // get product tags
+    productKeywords = delegator.findByAnd("ProductKeyword", ["productId": productId, "keywordTypeId" : "KWT_TAG", "statusId" : "KW_APPROVED"]);
+    keywordMap = [:];
+    if (productKeywords) {
+        for (productKeyword in productKeywords) {
+            keywordConds = [EntityCondition.makeCondition("keyword", EntityOperator.EQUALS, productKeyword.keyword),
+                            EntityCondition.makeCondition("keywordTypeId", EntityOperator.EQUALS, "KWT_TAG"),
+                            EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "KW_APPROVED")];
+                keywordCond = EntityCondition.makeCondition(keywordConds, EntityOperator.AND);
+            productKeyWordCount = delegator.findCountByCondition("ProductKeyword", keywordCond, null, null);
+            keywordMap.put(productKeyword.keyword,productKeyWordCount);
+        }
+        context.productTags = keywordMap;
+    }
 }

Added: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/tagsearch.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/tagsearch.ftl?rev=1222544&view=auto
==============================================================================
--- ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/tagsearch.ftl (added)
+++ ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/tagsearch.ftl Fri Dec 23 03:49:11 2011
@@ -0,0 +1,84 @@
+<#--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+<h1>${uiLabelMap.ProductProductTaggedWith} "${parameters.SEARCH_STRING}"</h1>
+
+<#if !productIds?has_content>
+  <h2>&nbsp;${uiLabelMap.ProductNoResultsFound}.</h2>
+</#if>
+
+<#if productIds?has_content>
+    <div class="product-prevnext">
+        <#-- Start Page Select Drop-Down -->
+        <#assign viewIndexMax = Static["java.lang.Math"].ceil((listSize - 1)?double / viewSize?double)>
+        <select name="pageSelect" onchange="window.location=this[this.selectedIndex].value;">
+          <option value="#">${uiLabelMap.CommonPage} ${viewIndex?int + 1} ${uiLabelMap.CommonOf} ${viewIndexMax + 1}</option>
+          <#list 0..viewIndexMax as curViewNum>
+            <option value="<@ofbizUrl>keywordsearch/~VIEW_SIZE=${viewSize}/~VIEW_INDEX=${curViewNum?int}/~clearSearch=N</@ofbizUrl>">${uiLabelMap.CommonGotoPage} ${curViewNum + 1}</option>
+          </#list>
+        </select>
+        <#-- End Page Select Drop-Down -->
+        <b>
+        <#if (viewIndex?int > 0)>
+          <a href="<@ofbizUrl>keywordsearch/~VIEW_SIZE=${viewSize}/~VIEW_INDEX=${viewIndex?int - 1}/~clearSearch=N</@ofbizUrl>" class="buttontext">${uiLabelMap.CommonPrevious}</a> |
+        </#if>
+        <#if (listSize?int > 0)>
+          <span>${lowIndex+1} - ${highIndex} ${uiLabelMap.CommonOf} ${listSize}</span>
+        </#if>
+        <#if highIndex?int < listSize?int>
+          | <a href="<@ofbizUrl>keywordsearch/~VIEW_SIZE=${viewSize}/~VIEW_INDEX=${viewIndex+1}/~clearSearch=N</@ofbizUrl>" class="buttontext">${uiLabelMap.CommonNext}</a>
+        </#if>
+        </b>
+    </div>
+</#if>
+
+<#if productIds?has_content>
+    <div class="productsummary-container">
+        <#list productIds as productId> <#-- note that there is no boundary range because that is being done before the list is put in the content -->
+            ${setRequestAttribute("optProductId", productId)}
+            ${setRequestAttribute("listIndex", productId_index)}
+            ${screens.render(productsummaryScreen)}
+        </#list>
+    </div>
+</#if>
+
+<#if productIds?has_content>
+    <div class="product-prevnext">
+        <#-- Start Page Select Drop-Down -->
+        <#assign viewIndexMax = Static["java.lang.Math"].ceil((listSize - 1)?double / viewSize?double)>
+        <select name="pageSelect" onchange="window.location=this[this.selectedIndex].value;">
+          <option value="#">${uiLabelMap.CommonPage} ${viewIndex?int + 1} ${uiLabelMap.CommonOf} ${viewIndexMax + 1}</option>
+          <#list 0..viewIndexMax as curViewNum>
+            <option value="<@ofbizUrl>keywordsearch/~VIEW_SIZE=${viewSize}/~VIEW_INDEX=${curViewNum?int}/~clearSearch=N</@ofbizUrl>">${uiLabelMap.CommonGotoPage} ${curViewNum + 1}</option>
+          </#list>
+        </select>
+        <#-- End Page Select Drop-Down -->
+        <b>
+        <#if (viewIndex?int > 0)>
+          <a href="<@ofbizUrl>keywordsearch/~VIEW_SIZE=${viewSize}/~VIEW_INDEX=${viewIndex?int - 1}/~clearSearch=N</@ofbizUrl>" class="buttontext">${uiLabelMap.CommonPrevious}</a> |
+        </#if>
+        <#if (listSize?int > 0)>
+          <span>${lowIndex+1} - ${highIndex} ${uiLabelMap.CommonOf} ${listSize}</span>
+        </#if>
+        <#if highIndex?int < listSize?int>
+          | <a href="<@ofbizUrl>keywordsearch/~VIEW_SIZE=${viewSize}/~VIEW_INDEX=${viewIndex+1}/~clearSearch=N</@ofbizUrl>" class="buttontext">${uiLabelMap.CommonNext}</a>
+        </#if>
+        </b>
+    </div>
+</#if>

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/tagsearch.ftl
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/tagsearch.ftl
------------------------------------------------------------------------------
    svn:keywords = Date Rev Author URL Id

Propchange: ofbiz/trunk/applications/order/webapp/ordermgr/entry/catalog/tagsearch.ftl
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: ofbiz/trunk/applications/product/config/ProductUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/config/ProductUiLabels.xml?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/config/ProductUiLabels.xml (original)
+++ ofbiz/trunk/applications/product/config/ProductUiLabels.xml Fri Dec 23 03:49:11 2011
@@ -3453,6 +3453,9 @@
         <value xml:lang="zh">关键字</value>
         <value xml:lang="zh_TW">關鍵字</value>
     </property>
+    <property key="FormFieldTitle_keywordType">
+        <value xml:lang="en">Keyword Type</value>
+    </property>
     <property key="FormFieldTitle_lastPrice">
         <value xml:lang="de">Letzter Preis</value>
         <value xml:lang="en">Last Price</value>
@@ -7433,6 +7436,9 @@
         <value xml:lang="zh">编辑产品订阅资源</value>
         <value xml:lang="zh_TW">編輯產品訂閱資源</value>
     </property>
+    <property key="PageTitleEditProductTags">
+        <value xml:lang="en">Edit Product Tags</value>
+    </property>
     <property key="PageTitleEditProductWorkEffort">
         <value xml:lang="de">Produkt Arbeitseinsatz bearbeiten</value>
         <value xml:lang="en">Edit Product Work Effort</value>
@@ -19765,6 +19771,9 @@
         <value xml:lang="zh">产品店铺网站</value>
         <value xml:lang="zh_TW">產品商店網站</value>
     </property>
+    <property key="ProductProductTaggedWith">
+        <value xml:lang="en">Product tagged with</value>
+    </property>
     <property key="ProductProductType">
         <value xml:lang="de">Produkttyp</value>
         <value xml:lang="en">Product Type</value>
@@ -23712,6 +23721,9 @@
         <value xml:lang="fr">Assoc.</value>
         <value xml:lang="it">TD</value>
     </property>
+    <property key="ProductTag">
+        <value xml:lang="en">Tag</value>
+    </property>
     <property key="ProductTargetProductCategory">
         <value xml:lang="de">Ziel Produktkategorie</value>
         <value xml:lang="en">Target Product Category</value>

Modified: ofbiz/trunk/applications/product/entitydef/entitymodel.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/entitydef/entitymodel.xml?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/entitydef/entitymodel.xml (original)
+++ ofbiz/trunk/applications/product/entitydef/entitymodel.xml Fri Dec 23 03:49:11 2011
@@ -3079,40 +3079,29 @@ under the License.
             <key-map field-name="productId"/>
         </view-link>
     </view-entity>
-    <entity entity-name="ProductKeyword" package-name="org.ofbiz.product.product" title="Product Keyword Entity" never-cache="true">
+    <entity entity-name="ProductKeyword" table-name="PRODUCT_KEYWORD_NEW"
+            package-name="org.ofbiz.product.product" title="Product Keyword Entity" never-cache="true">
       <field name="productId" type="id-ne"></field>
       <field name="keyword" type="short-varchar"></field>
+      <field name="keywordTypeId" type="id-ne"></field>
       <field name="relevancyWeight" type="numeric"></field>
+      <field name="statusId" type="id-ne"></field>
       <prim-key field="productId"/>
       <prim-key field="keyword"/>
+      <prim-key field="keywordTypeId"/>
       <relation type="one" fk-name="PROD_KWD_PROD" rel-entity-name="Product">
         <key-map field-name="productId"/>
       </relation>
+      <relation type="one" fk-name="PROD_KWD_TYPE" rel-entity-name="Enumeration">
+        <key-map field-name="keywordTypeId" rel-field-name="enumId"/>
+      </relation>
+      <relation type="one" fk-name="PROD_KWD_STTS" rel-entity-name="StatusItem">
+        <key-map field-name="statusId"/>
+      </relation>
       <index name="PROD_KWD_KWD">
         <index-field name="keyword"/>
       </index>
     </entity>
-    <entity entity-name="OldProductKeywordResult" table-name="PRODUCT_KEYWORD_RESULT"
-            package-name="org.ofbiz.product.product"
-            never-cache="true"
-            title="Product Keyword Result Entity">
-      <field name="productKeywordResultId" type="id-ne"></field>
-      <field name="visitId" type="id"></field>
-      <field name="productCategoryId" type="id"></field>
-      <field name="searchString" type="short-varchar"></field>
-      <field name="intraKeywordOperator" type="very-short"></field>
-      <field name="anyPrefix" type="indicator"></field>
-      <field name="anySuffix" type="indicator"></field>
-      <field name="removeStems" type="indicator"></field>
-      <field name="numResults" type="numeric"></field>
-      <prim-key field="productKeywordResultId"/>
-      <relation type="one" fk-name="PROD_KWDRES_VST" rel-entity-name="Visit">
-        <key-map field-name="visitId"/>
-      </relation>
-      <relation type="one-nofk" rel-entity-name="ProductCategory">
-        <key-map field-name="productCategoryId"/>
-      </relation>
-    </entity>
     <entity entity-name="ProductMeter" package-name="org.ofbiz.product.product" title="Product Meter Entity">
         <field name="productId" type="id-ne"></field>
         <field name="productMeterTypeId" type="id-ne"><description>Part of the primary key as different meters on a machine should have distinct types</description></field>

Modified: ofbiz/trunk/applications/product/entitydef/entitymodel_old.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/entitydef/entitymodel_old.xml?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/entitydef/entitymodel_old.xml (original)
+++ ofbiz/trunk/applications/product/entitydef/entitymodel_old.xml Fri Dec 23 03:49:11 2011
@@ -56,5 +56,41 @@ under the License.
         <key-map field-name="roleTypeId"/>
       </relation>
     </entity>
+    <entity entity-name="OldProductKeyword" table-name="PRODUCT_KEYWORD"
+            package-name="org.ofbiz.product.facility"
+            title="Old Product Keyword Entity">
+      <field name="productId" type="id-ne"></field>
+      <field name="keyword" type="short-varchar"></field>
+      <field name="relevancyWeight" type="numeric"></field>
+      <prim-key field="productId"/>
+      <prim-key field="keyword"/>
+      <relation type="one" fk-name="PROD_KWD_PROD" rel-entity-name="Product">
+        <key-map field-name="productId"/>
+      </relation>
+      <index name="PROD_KWD_KWD">
+        <index-field name="keyword"/>
+      </index>
+    </entity>
+    <entity entity-name="OldProductKeywordResult" table-name="PRODUCT_KEYWORD_RESULT"
+            package-name="org.ofbiz.product.product"
+            never-cache="true"
+            title="Product Keyword Result Entity">
+      <field name="productKeywordResultId" type="id-ne"></field>
+      <field name="visitId" type="id"></field>
+      <field name="productCategoryId" type="id"></field>
+      <field name="searchString" type="short-varchar"></field>
+      <field name="intraKeywordOperator" type="very-short"></field>
+      <field name="anyPrefix" type="indicator"></field>
+      <field name="anySuffix" type="indicator"></field>
+      <field name="removeStems" type="indicator"></field>
+      <field name="numResults" type="numeric"></field>
+      <prim-key field="productKeywordResultId"/>
+      <relation type="one" fk-name="PROD_KWDRES_VST" rel-entity-name="Visit">
+        <key-map field-name="visitId"/>
+      </relation>
+      <relation type="one-nofk" rel-entity-name="ProductCategory">
+        <key-map field-name="productCategoryId"/>
+      </relation>
+    </entity>
 
 </entitymodel>

Modified: ofbiz/trunk/applications/product/script/org/ofbiz/product/UpgradeServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/script/org/ofbiz/product/UpgradeServices.xml?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/script/org/ofbiz/product/UpgradeServices.xml (original)
+++ ofbiz/trunk/applications/product/script/org/ofbiz/product/UpgradeServices.xml Fri Dec 23 03:49:11 2011
@@ -56,4 +56,23 @@ under the License.
         </iterate>
     </simple-method>
 
+     <simple-method method-name="migrateProductKeyword" short-description="Migrate Data From OldProductKeyword To ProductKeyword">
+        <entity-condition entity-name="OldProductKeyword" list="oldProductKeywords"/>
+        <iterate list="oldProductKeywords" entry="oldProductKeyword">
+            <entity-one entity-name="ProductKeyword" value-field="checkProductKeyword">
+                <field-map field-name="productId" from-field="oldProductKeyword.productId"/>
+                <field-map field-name="keyword" from-field="oldProductKeyword.keyword"/>
+                <field-map field-name="keywordTypeId" value="KWT_KEYWORD"/>
+            </entity-one>
+            <if-empty field="checkProductKeyword">
+                <make-value entity-name="ProductKeyword" value-field="productKeyword"/>
+                <set field="productKeyword.productId" from-field="oldProductKeyword.productId"/>
+                <set field="productKeyword.keyword" from-field="oldProductKeyword.keyword"/>
+                <set field="productKeyword.keywordTypeId" value="KWT_KEYWORD"/>
+                <set field="productKeyword.relevancyWeight" from-field="oldProductKeyword.relevancyWeight"/>
+                <create-value value-field="productKeyword"/>
+            </if-empty>
+        </iterate>
+    </simple-method>
+
 </simple-methods>

Modified: ofbiz/trunk/applications/product/servicedef/services_upgrade.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/servicedef/services_upgrade.xml?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/servicedef/services_upgrade.xml (original)
+++ ofbiz/trunk/applications/product/servicedef/services_upgrade.xml Fri Dec 23 03:49:11 2011
@@ -41,5 +41,16 @@ under the License.
             The field Facility.squareFootageSince has been deprecated since revision 929912 (2010-04-01)
         </description>
     </service>
+    <service name="migrateProductKeyword" engine="simple"
+            location="component://product/script/org/ofbiz/product/UpgradeServices.xml" invoke="migrateProductKeyword">
+        <description>
+            Migrate data from oldProductKeyword to ProductKeyword.
+            The entity oldProductKeyword has been deprecated.
+            This service can be used to upgrade existing data from the oldProductKeyword entity to the new
+            ProductKeyword entity.
+            Before running this service, load the seed data for the KeywordType entity from the file:
+            common/data/CommonTypeData.xml
+        </description>
+    </service>
 
 </services>

Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/KeywordIndex.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/product/KeywordIndex.java?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/src/org/ofbiz/product/product/KeywordIndex.java (original)
+++ ofbiz/trunk/applications/product/src/org/ofbiz/product/product/KeywordIndex.java Fri Dec 23 03:49:11 2011
@@ -194,7 +194,7 @@ public class KeywordIndex {
         int keywordMaxLength = Integer.parseInt(UtilProperties.getPropertyValue("prodsearch", "product.keyword.max.length"));
         for (Map.Entry<String, Long> entry: keywords.entrySet()) {
             if (entry.getKey().length() <= keywordMaxLength) {
-                GenericValue productKeyword = delegator.makeValue("ProductKeyword", UtilMisc.toMap("productId", product.getString("productId"), "keyword", entry.getKey(), "relevancyWeight", entry.getValue()));
+                GenericValue productKeyword = delegator.makeValue("ProductKeyword", UtilMisc.toMap("productId", product.getString("productId"), "keyword", entry.getKey(), "keywordTypeId", "KWT_KEYWORD", "relevancyWeight", entry.getValue()));
                 toBeStored.add(productKeyword);
             }
         }

Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductEvents.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductEvents.java?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductEvents.java (original)
+++ ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductEvents.java Fri Dec 23 03:49:11 2011
@@ -24,6 +24,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -1170,5 +1172,43 @@ public class ProductEvents {
         }
         return new BigDecimal(bigDecimalString);
     }
-
-}
+    
+    /** Event add product tags */
+    public static String addProductTags (HttpServletRequest request, HttpServletResponse response) {
+        Delegator delegator = (Delegator) request.getAttribute("delegator");
+        LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
+        String productId = request.getParameter("productId");
+        String productTags = request.getParameter("productTags");
+        if (UtilValidate.isNotEmpty(productId) && UtilValidate.isNotEmpty(productTags)) {
+            List<String> matchList = FastList.newInstance();
+            Pattern regex = Pattern.compile("[^\\s\"']+|\"([^\"]*)\"|'([^']*)'");
+            Matcher regexMatcher = regex.matcher(productTags);
+            while (regexMatcher.find()) {
+                matchList.add(regexMatcher.group().replace("'", ""));
+            }
+            
+            GenericValue userLogin = (GenericValue) request.getSession().getAttribute("userLogin");
+            if (UtilValidate.isEmpty(userLogin)) {
+                try {
+                    userLogin = delegator.findByPrimaryKeyCache("UserLogin", UtilMisc.toMap("userLoginId", "system"));
+                } catch (GenericEntityException e) {
+                    request.setAttribute("_ERROR_MESSAGE_", e.getMessage());
+                    return "error";
+                }
+                
+            }
+            
+            if(UtilValidate.isNotEmpty(matchList)) {
+                for (String keywordStr : matchList) {
+                    try {
+                        dispatcher.runSync("createProductKeyword", UtilMisc.toMap("productId", productId, "keyword", keywordStr.trim(), "keywordTypeId", "KWT_TAG","statusId","KW_PENDING" , "userLogin", userLogin));
+                    } catch (GenericServiceException e) {
+                        request.setAttribute("_ERROR_MESSAGE_", e.getMessage());
+                        return "error";
+                    }
+                }
+            }
+        }
+        return "success";
+    }
+}
\ No newline at end of file

Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearch.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearch.java?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearch.java (original)
+++ ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearch.java Fri Dec 23 03:49:11 2011
@@ -181,6 +181,9 @@ public class ProductSearch {
         public Set<String> excludeFeatureGroupIds = FastSet.newInstance();
         public Set<String> alwaysIncludeFeatureGroupIds = FastSet.newInstance();
 
+        public List<String> keywordTypeIds = FastList.newInstance();
+        public String statusId = null;
+
         public ProductSearchContext(Delegator delegator, String visitId) {
             this.delegator = delegator;
             this.visitId = visitId;
@@ -282,9 +285,34 @@ public class ProductSearch {
 
                     dynamicViewEntity.addMemberEntity(entityAlias, "ProductKeyword");
                     dynamicViewEntity.addAlias(entityAlias, prefix + "Keyword", "keyword", null, null, null, null);
+                    
+                    // keyword type filter
+                    if (UtilValidate.isNotEmpty(keywordTypeIds)) {
+                        dynamicViewEntity.addAlias(entityAlias, "keywordTypeId");
+                    }
+                    
+                    // keyword status filter
+                    if (UtilValidate.isNotEmpty(statusId)) {
+                        dynamicViewEntity.addAlias(entityAlias, "statusId");
+                    }
+                    
                     dynamicViewEntity.addViewLink("PROD", entityAlias, Boolean.FALSE, ModelKeyMap.makeKeyMapList("productId"));
                     entityConditionList.add(EntityCondition.makeCondition(prefix + "Keyword", EntityOperator.LIKE, keyword));
-
+                    
+                    // keyword type filter
+                    if (UtilValidate.isNotEmpty(keywordTypeIds)) {
+                        List<EntityCondition> keywordTypeCons = FastList.newInstance();
+                        for (String keywordTypeId : keywordTypeIds) {
+                            keywordTypeCons.add(EntityCondition.makeCondition("keywordTypeId", EntityOperator.EQUALS, keywordTypeId));
+                        }
+                        entityConditionList.add(EntityCondition.makeCondition(keywordTypeCons, EntityOperator.OR));
+                    }
+                    
+                    // keyword status filter
+                    if (UtilValidate.isNotEmpty(statusId)) {
+                        entityConditionList.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, statusId));
+                    }
+                    
                     //don't add an alias for this, will be part of a complex alias: dynamicViewEntity.addAlias(entityAlias, prefix + "RelevancyWeight", "relevancyWeight", null, null, null, null);
                     //needed when doingBothAndOr or will get an SQL error
                     if (doingBothAndOr) {

Modified: ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchSession.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchSession.java?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchSession.java (original)
+++ ofbiz/trunk/applications/product/src/org/ofbiz/product/product/ProductSearchSession.java Fri Dec 23 03:49:11 2011
@@ -859,6 +859,7 @@ public class ProductSearchSession {
         productSearchOptions.setPaging((String) parameters.get("PAGING"));
     }
 
+    @SuppressWarnings("unchecked")
     public static Map<String, Object> getProductSearchResult(HttpServletRequest request, Delegator delegator, String prodCatalogId) {
 
         // ========== Create View Indexes
@@ -869,6 +870,14 @@ public class ProductSearchSession {
         int listSize = 0;
         String paging = "Y";
         int previousViewSize = 20;
+        Map<String, Object> requestParams = UtilHttp.getCombinedMap(request);
+        List<String> keywordTypeIds = FastList.newInstance();
+        if (requestParams.get("keywordTypeId") instanceof String) {
+            keywordTypeIds.add((String) requestParams.get("keywordTypeId"));
+        } else if (requestParams.get("keywordTypeId") instanceof List){
+            keywordTypeIds = (List<String>) requestParams.get("keywordTypeId");
+        }
+        String statusId = (String) requestParams.get("statusId");
 
         HttpSession session = request.getSession();
         ProductSearchOptions productSearchOptions = getProductSearchOptions(session);
@@ -902,7 +911,6 @@ public class ProductSearchSession {
         List<String> productIds = FastList.newInstance();
         String visitId = VisitHandler.getVisitId(session);
         List<ProductSearchConstraint> productSearchConstraintList = ProductSearchOptions.getConstraintList(session);
-        Map<String, Object> requestParams = UtilHttp.getParameterMap(request);
         String noConditionFind = (String) requestParams.get("noConditionFind");
         if (UtilValidate.isEmpty(noConditionFind)) {
             noConditionFind = UtilProperties.getPropertyValue("widget", "widget.defaultNoConditionFind");
@@ -965,7 +973,17 @@ public class ProductSearchSession {
             productSearchContext.setResultSortOrder(resultSortOrder);
             productSearchContext.setResultOffset(resultOffset);
             productSearchContext.setMaxResults(maxResults);
-
+            
+            if (UtilValidate.isNotEmpty(keywordTypeIds)) {
+                productSearchContext.keywordTypeIds = keywordTypeIds;
+            } else {
+                 productSearchContext.keywordTypeIds = UtilMisc.toList("KWT_KEYWORD");
+            }
+            
+            if (UtilValidate.isNotEmpty(statusId)) {
+                productSearchContext.statusId = statusId;
+            }
+            
             List<String> foundProductIds = productSearchContext.doSearch();
             if (maxResultsInt > 0) {
                 productIds.addAll(foundProductIds);

Modified: ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml (original)
+++ ofbiz/trunk/applications/product/webapp/catalog/WEB-INF/controller.xml Fri Dec 23 03:49:11 2011
@@ -800,6 +800,12 @@ under the License.
         <response name="success" type="view" value="EditProductKeyword"/>
         <response name="error" type="view" value="EditProductKeyword"/>
     </request-map>
+    <request-map uri="updateProductKeyword">
+        <security https="true" auth="true"/>
+        <event type="service" path="" invoke="updateProductKeyword"/>
+        <response name="success" type="view" value="EditProductKeyword"/>
+        <response name="error" type="view" value="EditProductKeyword"/>
+    </request-map>
     <request-map uri="deleteProductKeyword">
         <security https="true" auth="true"/>
         <event type="service" path="" invoke="deleteProductKeyword"/>

Modified: ofbiz/trunk/applications/product/widget/catalog/ProductForms.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/widget/catalog/ProductForms.xml?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/widget/catalog/ProductForms.xml (original)
+++ ofbiz/trunk/applications/product/widget/catalog/ProductForms.xml Fri Dec 23 03:49:11 2011
@@ -1951,13 +1951,95 @@ under the License.
         <auto-fields-service service-name="createProductKeyword"/>
         <field name="productId"><hidden/></field>
         <field name="relevancyWeight"><text default-value="1"/></field>
+        <field name="keywordTypeId">
+            <drop-down>
+                <entity-options entity-name="Enumeration" key-field-name="enumId" description="${description}">
+                    <entity-constraint name="enumTypeId" operator="equals" value="KEYWORD_TYPE"/>
+                    <entity-order-by field-name="description"/>
+                </entity-options>
+            </drop-down>
+        </field>
+        <field name="statusId">
+            <drop-down allow-empty="true">
+                <entity-options entity-name="StatusItem" key-field-name="statusId" description="${description}">
+                    <entity-constraint name="statusTypeId" value="KEYWORD_STATUS"/>
+                    <entity-order-by field-name="sequenceId"/>
+                </entity-options>
+            </drop-down>
+        </field>
         <field name="submitButton" title="${uiLabelMap.CommonCreate}"><submit button-type="button"/></field>
     </form>
-    <form name="UpdateProductKeyword" type="list" target="deleteProductKeyword" title="" list-name="productKeywords"
+    <form name="UpdateProductKeyword" type="list" target="updateProductKeyword" title="" list-name=""
+        odd-row-style="alternate-row" default-table-style="basic-table">
+        <actions>
+            <entity-condition entity-name="ProductKeyword">
+                <condition-list combine="and">
+                    <condition-expr field-name="productId" operator="equals" from-field="productId"/>
+                    <condition-expr field-name="keywordTypeId" operator="equals" value="KWT_KEYWORD"/>
+                </condition-list>
+                <order-by field-name="statusId"/>
+                <order-by field-name="-relevancyWeight"/>
+                <order-by field-name="keyword"/>
+            </entity-condition>
+        </actions>
+        <field name="productId"><hidden/></field>
+        <field name="keyword"><display/></field>
+        <field name="keywordTypeId" title="${uiLabelMap.FormFieldTitle_keywordType}">
+            <display-entity entity-name="Enumeration" description="${description}" key-field-name="enumId"/>
+        </field>
+        <field name="relevancyWeight"><display/></field>
+        <field name="statusId">
+            <drop-down allow-empty="true">
+                <entity-options entity-name="StatusItem" key-field-name="statusId" description="${description}">
+                    <entity-constraint name="statusTypeId" value="KEYWORD_STATUS"/>
+                    <entity-order-by field-name="sequenceId"/>
+                </entity-options>
+            </drop-down>
+        </field>
+        <field name="submitButton" title="${uiLabelMap.CommonUpdate}"><submit button-type="button"/></field>
+        <field name="deleteLink" title="${uiLabelMap.CommonEmptyHeader}" widget-style="buttontext">
+            <hyperlink target="deleteProductKeyword" description="${uiLabelMap.CommonDelete}" also-hidden="false">
+                <parameter param-name="productId"/>
+                <parameter param-name="keyword"/>
+                <parameter param-name="keywordTypeId"/>
+            </hyperlink>
+        </field>
+    </form>
+    <form name="UpdateProductTag" type="list" target="updateProductKeyword" title="" list-name=""
         odd-row-style="alternate-row" default-table-style="basic-table">
-        <auto-fields-entity entity-name="ProductKeyword" default-field-type="display"/>
+        <actions>
+            <entity-condition entity-name="ProductKeyword">
+                <condition-list combine="and">
+                    <condition-expr field-name="productId" operator="equals" from-field="productId"/>
+                    <condition-expr field-name="keywordTypeId" operator="equals" value="KWT_TAG"/>
+                </condition-list>
+                <order-by field-name="statusId"/>
+                <order-by field-name="-relevancyWeight"/>
+                <order-by field-name="keyword"/>
+            </entity-condition>
+        </actions>
         <field name="productId"><hidden/></field>
-        <field name="submitButton" title="${uiLabelMap.CommonDelete}"><submit button-type="button"/></field>
+        <field name="keyword" title="${uiLabelMap.ProductTag}"><display/></field>
+        <field name="keywordTypeId" title="${uiLabelMap.FormFieldTitle_keywordType}">
+            <display-entity entity-name="Enumeration" description="${description}" key-field-name="enumId"/>
+        </field>
+        <field name="relevancyWeight"><display/></field>
+        <field name="statusId">
+            <drop-down allow-empty="true">
+                <entity-options entity-name="StatusItem" key-field-name="statusId" description="${description}">
+                    <entity-constraint name="statusTypeId" value="KEYWORD_STATUS"/>
+                    <entity-order-by field-name="sequenceId"/>
+                </entity-options>
+            </drop-down>
+        </field>
+        <field name="submitButton" title="${uiLabelMap.CommonUpdate}"><submit button-type="button"/></field>
+        <field name="deleteLink" title="${uiLabelMap.CommonEmptyHeader}" widget-style="buttontext">
+            <hyperlink target="deleteProductKeyword" description="${uiLabelMap.CommonDelete}" also-hidden="false">
+                <parameter param-name="productId"/>
+                <parameter param-name="keyword"/>
+                <parameter param-name="keywordTypeId"/>
+            </hyperlink>
+        </field>
     </form>
     <!-- ProductAttribute -->
     <form name="AddProductAttribute" type="single" target="createProductAttribute" title=""

Modified: ofbiz/trunk/applications/product/widget/catalog/ProductScreens.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/product/widget/catalog/ProductScreens.xml?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/applications/product/widget/catalog/ProductScreens.xml (original)
+++ ofbiz/trunk/applications/product/widget/catalog/ProductScreens.xml Fri Dec 23 03:49:11 2011
@@ -621,9 +621,6 @@ under the License.
                 <set field="labelTitleProperty" value="ProductKeywords"/>
                 <set field="productId" from-field="parameters.productId"/>
                 <entity-one entity-name="Product" value-field="product"/>
-                <set field="orderByList[]" value="-relevancyWeight"/>
-                <set field="orderByList[]" value="keyword"/>
-                <get-related value-field="product" relation-name="ProductKeyword" list="productKeywords" order-by-list="orderByList"/>
             </actions>
             <widgets>
                 <decorator-screen name="CommonProductDecorator" location="${parameters.productDecoratorLocation}">
@@ -642,6 +639,9 @@ under the License.
                         <screenlet title="${uiLabelMap.PageTitleEditProductKeywords}">
                             <include-form name="UpdateProductKeyword" location="component://product/widget/catalog/ProductForms.xml"/>
                         </screenlet>
+                        <screenlet title="${uiLabelMap.PageTitleEditProductTags}">
+                            <include-form name="UpdateProductTag" location="component://product/widget/catalog/ProductForms.xml"/>
+                        </screenlet>
                     </decorator-section>
                 </decorator-screen>
             </widgets>

Modified: ofbiz/trunk/framework/common/data/CommonTypeData.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/data/CommonTypeData.xml?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/framework/common/data/CommonTypeData.xml (original)
+++ ofbiz/trunk/framework/common/data/CommonTypeData.xml Fri Dec 23 03:49:11 2011
@@ -141,4 +141,15 @@ under the License.
     <ServerHitType description="Entity" hitTypeId="ENTITY"/>
     <ServerHitType description="Service" hitTypeId="SERVICE"/>
 
+    <!-- Keyword Type -->
+    <EnumerationType enumTypeId="KEYWORD_TYPE" hasTable="N" description="Keyword Type"/>
+    <Enumeration enumId="KWT_KEYWORD" enumTypeId="KEYWORD_TYPE" enumCode="KEYWORD" sequenceId="01" description="Keyword"/>
+    <Enumeration enumId="KWT_TAG" enumTypeId="KEYWORD_TYPE" enumCode="TAG" sequenceId="02" description="Tag"/>
+
+    <!-- Keyword Status -->
+    <StatusType statusTypeId="KEYWORD_STATUS" hasTable="N" description="Keyword"/>
+    <StatusItem statusId="KW_APPROVED" statusTypeId="KEYWORD_STATUS" statusCode="APPROVED" sequenceId="01" description="Approved"/>
+    <StatusItem statusId="KW_PENDING" statusTypeId="KEYWORD_STATUS" statusCode="PENDING" sequenceId="02" description="Pending"/>
+    <StatusItem statusId="KW_DISAPPROVED" statusTypeId="KEYWORD_STATUS" statusCode="DISAPPROVED" sequenceId="03" description="Disapproved"/>
+
 </entity-engine-xml>

Modified: ofbiz/trunk/specialpurpose/ecommerce/config/EcommerceUiLabels.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/config/EcommerceUiLabels.xml?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/config/EcommerceUiLabels.xml (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/config/EcommerceUiLabels.xml Fri Dec 23 03:49:11 2011
@@ -184,6 +184,12 @@
         <value xml:lang="zh">把选中的添加到列表中</value>
         <value xml:lang="zh_TW">把選中項目加到列表</value>
     </property>
+    <property key="EcommerceAddTags">
+        <value xml:lang="en">Add Tags</value>
+    </property>
+    <property key="EcommerceAddTagsDetail">
+        <value xml:lang="en">Use spaces to separate tags. Use single quotes(') for phrases.</value>
+    </property>
     <property key="EcommerceAdditionalAddresses">
         <value xml:lang="da">Ekstra adresser</value>
         <value xml:lang="de">Zusätzliche Adressen</value>
@@ -206,6 +212,9 @@
         <value xml:lang="zh">地址簿</value>
         <value xml:lang="zh_TW">地址簿</value>
     </property>
+    <property key="EcommerceAddYourTags">
+        <value xml:lang="en">Add your tags</value>
+    </property>
     <property key="EcommerceAdjustment">
         <value xml:lang="cs">Úprava</value>
         <value xml:lang="da">Justering</value>
@@ -2565,6 +2574,12 @@
         <value xml:lang="zh">产品标识:</value>
         <value xml:lang="zh_TW">產品ID:</value>
     </property>
+    <property key="EcommerceProductTags">
+        <value xml:lang="en">Product Tags</value>
+    </property>
+    <property key="EcommerceProductTagsDetail">
+        <value xml:lang="en">Other people marked this product with these tags</value>
+    </property>
     <property key="EcommercePromotionalItems">
         <value xml:lang="cs">Reklamní položka; množství nelze změnit</value>
         <value xml:lang="da">Reklameartikler</value>

Modified: ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/WEB-INF/controller.xml Fri Dec 23 03:49:11 2011
@@ -908,6 +908,12 @@ under the License.
         <response name="success" type="view" value="keywordsearch"/>
         <response name="none" type="none" value=""/>
     </request-map>
+    <request-map uri="tagsearch">
+        <security https="false" auth="false"/>
+        <event type="java" path="org.ofbiz.product.product.ProductSearchSession" invoke="checkDoKeywordOverride"/>
+        <response name="success" type="view" value="tagsearch"/>
+        <response name="none" type="none" value=""/>
+    </request-map>
     <request-map uri="clearSearchOptionsHistoryList">
         <security https="false" auth="false"/>
         <event type="java" path="org.ofbiz.product.product.ProductSearchSession" invoke="clearSearchOptionsHistoryList"/>
@@ -2007,6 +2013,14 @@ under the License.
         <response name="success" type="view" value="showShoppingList" save-current-view="true"/>
     </request-map>
     
+    <!-- Product Tags -->
+    <request-map uri="addProductTags">
+        <security https="false" auth="false"/>
+        <event type="java" path="org.ofbiz.product.product.ProductEvents" invoke="addProductTags"/>
+        <response name="success" type="view-last" save-current-view="true"/>
+        <response name="error" type="view-last" save-current-view="true"/>
+    </request-map>
+    
     <!-- End of Request Mappings -->
 
     <!-- View Mappings -->
@@ -2033,6 +2047,7 @@ under the License.
     <view-map name="productReview" type="screen" page="component://ecommerce/widget/CatalogScreens.xml#productreview"/>
 
     <view-map name="keywordsearch" type="screen" page="component://ecommerce/widget/CatalogScreens.xml#keywordsearch"/>
+    <view-map name="tagsearch" type="screen" page="component://ecommerce/widget/CatalogScreens.xml#tagsearch"/>
     <view-map name="advancedsearch" type="screen" page="component://ecommerce/widget/CatalogScreens.xml#advancedsearch"/>
 
     <view-map name="tellafriend" type="screen" page="component://ecommerce/widget/CatalogScreens.xml#tellafriend"/>

Modified: ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/webapp/ecommerce/catalog/productdetail.ftl Fri Dec 23 03:49:11 2011
@@ -305,6 +305,17 @@ ${virtualVariantJavaScript?if_exists}
         }
     }
 //]]>
+$(function(){
+    $('a[id^=productTag_]').click(function(){
+        var id = $(this).attr('id');
+        var ids = id.split('_');
+        var productTagStr = ids[1];
+        if (productTagStr) {
+            $('#productTagStr').val(productTagStr);
+            $('#productTagsearchform').submit();
+        }
+    });
+})
  </script>
 
 <#macro showUnavailableVarients>
@@ -865,5 +876,44 @@ ${virtualVariantJavaScript?if_exists}
             </#list>
         </div>
     </#if>
+    <div class="product-tags">
+        <p class="titleProductTags"><h3>${uiLabelMap.EcommerceProductTags}</h3></p>
+        <#if productTags?exists>
+            <p class="titleAddTags"><strong>${uiLabelMap.EcommerceProductTagsDetail}:</strong></p>
+            <p>
+                <ul>
+                    <li>
+                    <#assign no = 0 />
+                    <#list productTags?keys?sort as productTag>
+                        <#assign tagValue = productTags.get(productTag)?if_exists/>
+                        <#if tagValue?has_content>
+                              <span><a href="javascript:void(0);" id="productTag_${productTag}">${productTag}</a> (${tagValue}) <#if no < (productTags.size() - 1)> | </#if></span>
+                              <#assign no = no + 1 />
+                        </#if>
+                    </#list>
+                    </li>
+                </ul>
+            </p>
+        </#if>
+        
+        <p class="titleAddTags"><strong>${uiLabelMap.EcommerceAddYourTags}:</strong></p>
+        <p>
+            <form method="post" action="<@ofbizUrl>addProductTags</@ofbizUrl>" name="addProductTags">
+                <input type="hidden" name="productId" value="${product.productId?if_exists}"/>
+                <input class="inputProductTags" type="text" value="" name="productTags" id="productTags" size="40"/>
+                <input class="buttonProductTags" type="submit" value="${uiLabelMap.EcommerceAddTags}" name="addTag"/>
+            </form>
+            <span>${uiLabelMap.EcommerceAddTagsDetail}</span>
+        </p>
+    </div>
+    <hr />
+    <form action="<@ofbizUrl>tagsearch</@ofbizUrl>" method="post" name="productTagsearchform" id="productTagsearchform">
+        <input type="hidden" name="keywordTypeId" value="KWT_TAG"/>
+        <input type="hidden" name="statusId" value="KW_APPROVED"/>
+        <input type="hidden" name="clearSearch" value="Y"/>
+        <input type="hidden" name="VIEW_SIZE" value="10"/>
+        <input type="hidden" name="PAGING" value="Y"/>
+        <input type="hidden" name="SEARCH_STRING" id="productTagStr"/>
+    </form>
     </div>
 </div>

Modified: ofbiz/trunk/specialpurpose/ecommerce/widget/CatalogScreens.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/ecommerce/widget/CatalogScreens.xml?rev=1222544&r1=1222543&r2=1222544&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/ecommerce/widget/CatalogScreens.xml (original)
+++ ofbiz/trunk/specialpurpose/ecommerce/widget/CatalogScreens.xml Fri Dec 23 03:49:11 2011
@@ -430,6 +430,29 @@ under the License.
         </section>
     </screen>
 
+    <screen name="tagsearch">
+        <section>
+            <actions>
+                <set field="leftbarScreenName" value="leftbar"/>
+                <set field="rightbarScreenName" value="rightbar"/>
+                <set field="MainColumnStyle" value="center"/>
+
+                <set field="productsummaryScreen" value="component://ecommerce/widget/CatalogScreens.xml#productsummary"/>
+
+                <set field="titleProperty" value="PageTitleTagResults"/>
+                <set field="parameters.VIEW_SIZE" from-field="parameters.VIEW_SIZE" default-value="10"/>
+                <script location="component://order/webapp/ordermgr/WEB-INF/actions/entry/catalog/KeywordSearch.groovy"/>
+            </actions>
+            <widgets>
+                <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}">
+                    <decorator-section name="body">
+                        <platform-specific><html><html-template location="component://order/webapp/ordermgr/entry/catalog/tagsearch.ftl"/></html></platform-specific>
+                    </decorator-section>
+                </decorator-screen>
+            </widgets>
+        </section>
+    </screen>
+
     <screen name="advancedsearch">
         <section>
             <actions>