- Localisation for Search (ResultsPane), Ticket #1762

- Some formating


git-svn-id: https://svn.libreccm.org/ccm/trunk@2553 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2014-03-04 18:35:21 +00:00
parent ef8618fad2
commit c21769dfc8
15 changed files with 490 additions and 353 deletions

View File

@ -1068,3 +1068,5 @@ cms.ui.move.category=Move category "{0}" to
cms.ui.category.move=Move category
cms.ui.category.cantmoved=This category can't be moved
cms.ui.authoring.error_conflicts_with_this_url=There are conflicts with this URL. Specifically, there is at least one item in the same category as this item with the name (url) of
cms.ui.search.help=To search for content items, please enter at least 3 letters into the search field. You can narrow the result by using additional parameters.
cms.ui.search.no_results=Sorry. Not content items found which match your search.

View File

@ -1062,3 +1062,5 @@ cms.ui.move.category=Verschiebe Kategorie "{0}" nach
cms.ui.category.move=Kategorie verschieben
cms.ui.category.cantmoved=Diese Kategorie kann nicht verschoben werden
cms.ui.authoring.error_conflicts_with_this_url=Es gibt Konflikte mit dieser URL. Insbesondere gibt es mindestens ein Dokument in der gleichen Kategorie wie dieser mit dem Namen (URL)
cms.ui.search.help=Geben sie mindestens drei Buchstaben ein, um nach Content Items zu suchen. Sie k\u00f6nnen das Ergebnis mit weiteren Parametern einschr\u00e4nken.
cms.ui.search.no_results=Es wurden keine Content Items gefunden, die Ihren Suchparametern entsprechen

View File

@ -116,3 +116,5 @@ cms.ui.move.category=Move category "{0}" to
cms.ui.category.move=Move category
cms.ui.category.cantmoved=This category can't be moved
cms.ui.authoring.error_conflicts_with_this_url=There are conflicts with this URL. Specifically, there is at least one item in the same category as this item with the name (url) of
cms.ui.search.help=
cms.ui.search.no_results=

View File

@ -590,3 +590,5 @@ cms.ui.move.category=Move category "{0}" to
cms.ui.category.move=Move category
cms.ui.category.cantmoved=This category can't be moved
cms.ui.authoring.error_conflicts_with_this_url=There are conflicts with this URL. Specifically, there is atleast one item in the same category as this item with the name (url) of
cms.ui.search.help=
cms.ui.search.no_results=

View File

@ -22,6 +22,7 @@ import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.persistence.OID;
import com.arsdigita.xml.Element;
@ -105,6 +106,8 @@ public class ItemSearchPopup extends ItemSearch {
public PopupResultsPane(QueryGenerator generator) {
super(generator);
setRelativeURLs(true);
setSearchHelpMsg(GlobalizationUtil.globalize("cms.ui.search.help"));
setNoResultsMsg(GlobalizationUtil.globalize("cms.ui.search.no_results"));
}
@Override

View File

@ -29,8 +29,10 @@ import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentType;
import com.arsdigita.cms.ui.search.ItemQueryComponent;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.search.ui.ResultsPane;
import com.arsdigita.search.ui.QueryGenerator;
@ -139,6 +141,8 @@ public class ItemSearchSection extends FormSection
protected Component createResultsPane(QueryGenerator generator) {
ResultsPane pane = new ResultsPane(generator);
pane.setRelativeURLs(true);
pane.setSearchHelpMsg(GlobalizationUtil.globalize("cms.ui.search.help"));
pane.setNoResultsMsg(GlobalizationUtil.globalize("cms.ui.search.no_results"));
return pane;
}

View File

@ -27,6 +27,7 @@ import com.arsdigita.toolbox.ui.OIDParameter;
import com.arsdigita.persistence.OID;
import com.arsdigita.cms.ContentItem;
import com.arsdigita.cms.ContentType;
import com.arsdigita.cms.util.GlobalizationUtil;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.xml.Element;
@ -154,6 +155,8 @@ public class ItemSearchSectionInline extends ItemSearchSection {
public InlineResultsPane(QueryGenerator query) {
super(query);
setRelativeURLs(true);
setSearchHelpMsg(GlobalizationUtil.globalize("cms.ui.search.help"));
setNoResultsMsg(GlobalizationUtil.globalize("cms.ui.search.no_results"));
}
@Override

View File

@ -51,12 +51,12 @@ import java.util.ArrayList;
import java.util.Collection;
/**
* A form for editing subclasses of ContentItem. This is just a convenience
* class.
* A form for editing subclasses of ContentItem. This is just a convenience class.
*
* @author Stanislav Freidin (stas@arsdigita.com)
* @version $Revision: #13 $ $DateTime: 2004/08/17 23:15:09 $
**/
*
*/
public abstract class BasicItemForm extends FormSection
implements FormInitListener,
FormProcessListener,
@ -79,8 +79,8 @@ public abstract class BasicItemForm extends FormSection
*
*
* @param formName the name of this form
* @param itemModel The {@link ItemSelectionModel} which will
* be responsible for loading the current item
* @param itemModel The {@link ItemSelectionModel} which will be responsible for loading the
* current item
*/
public BasicItemForm(String formName, ItemSelectionModel itemModel) {
super(new ColumnPanel(2));
@ -110,13 +110,12 @@ public abstract class BasicItemForm extends FormSection
}
/**
* Construct a new BasicItemForm with a specified number of ColumnPanels
* and without any content
* Construct a new BasicItemForm with a specified number of ColumnPanels and without any content
*
* @param formName the name of this form
* @param columnPanel the columnpanel of the form
* @param itemModel The {@link ItemSelectionModel} which will
* be responsible for loading the current item
* @param itemModel The {@link ItemSelectionModel} which will be responsible for loading the
* current item
*/
public BasicItemForm(String formName,
ColumnPanel columnPanel,
@ -137,7 +136,6 @@ public abstract class BasicItemForm extends FormSection
super.add(m_saveCancelSection, ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
}
/**
* Currently, to insert javascript code the Label Widget is "abused".
*/
@ -148,10 +146,9 @@ public abstract class BasicItemForm extends FormSection
/**
* Add basic widgets to the form.
*
* Widgets added are 'title' and 'name (url)' which are part of any content
* item.
* Child classes will override this method to perform all their widget-adding
* needs but may use super() to add the basic widgets.
* Widgets added are 'title' and 'name (url)' which are part of any content item. Child classes
* will override this method to perform all their widget-adding needs but may use super() to add
* the basic widgets.
*/
protected void addWidgets() {
//add(new FormErrorDisplay(this), ColumnPanel.FULL_WIDTH | ColumnPanel.LEFT);
@ -172,7 +169,6 @@ public abstract class BasicItemForm extends FormSection
// created you don't want to subsequently change it since
// it breaks URLs & potentially overwrites the user's
// customizations.
// For some content types it is maybe useful to change the label of the
// title field to something different than 'title'.
// This can nowbe done by overwriting the getTitleLabel() method.
@ -230,25 +226,28 @@ public abstract class BasicItemForm extends FormSection
}
/**
* Perform form initialization. Children should override this
* this method to pre-fill the widgets with data, instantiate
* the content item, etc.
* Perform form initialization. Children should override this this method to pre-fill the
* widgets with data, instantiate the content item, etc.
*
* @param e
*
* @throws FormProcessException
*/
public abstract void init(FormSectionEvent e) throws FormProcessException;
/**
* Process the form. Children should override this method to save
* the user's changes to the database.
* Process the form. Children should override this method to save the user's changes to the
* database.
*
* @param e
*
* @throws FormProcessException
*/
public abstract void process(FormSectionEvent e) throws FormProcessException;
/**
* Validate the form. Children should override this method to provide
* custom form validation.
* Validate the form. Children should override this method to provide custom form validation.
*
* @param e
*/
public void validate(FormSectionEvent e) throws FormProcessException {
@ -256,14 +255,14 @@ public abstract class BasicItemForm extends FormSection
}
/**
* Ensure that the name of an item is unique within a folder. A "New
* item" form should call this method in the validation listener.
* Ensure that the name of an item is unique within a folder. A "New item" form should call this
* method in the validation listener.
*
* @param parent the folder in which to check
* @param event the {@link FormSectionEvent} which was passed to the
* validation listener
* @throws FormProcessException if the folder already contains an item
* with the name the user provided on the input form.
* @param event the {@link FormSectionEvent} which was passed to the validation listener
*
* @throws FormProcessException if the folder already contains an item with the name the user
* provided on the input form.
*/
public void validateNameUniqueness(Folder parent, FormSectionEvent event)
throws FormProcessException {
@ -279,6 +278,7 @@ public abstract class BasicItemForm extends FormSection
* @param parent
* @param event
* @param newName
*
* @throws FormProcessException
*/
public void validateNameUniqueness(Folder parent, FormSectionEvent event,
@ -304,16 +304,20 @@ public abstract class BasicItemForm extends FormSection
}
if (item == null) {
// this means it is a creation form
// throw new FormProcessException(
// "An item with this name already exists");
throw new FormProcessException(
"An item with this name already exists");
"cms.ui.authoring.an_item_with_this_name_already_exists");
}
Collection list = getAllVersionIDs(item);
while (dq.next()) {
itemID = (BigDecimal) dq.get("itemID");
if (!list.contains(itemID)) {
dq.close();
// throw new FormProcessException(
// "An item with this name already exists");
throw new FormProcessException(
"An item with this name already exists");
"cms.ui.authoring.an_item_with_this_name_already_exists");
}
}
}
@ -321,15 +325,14 @@ public abstract class BasicItemForm extends FormSection
}
/**
* Ensure that the name of an item is unique within a category. This
* should only be called from the validation listener of an "edit" form.
* Ensure that the name of an item is unique within a category. This should only be called from
* the validation listener of an "edit" form.
*
* @param event the {@link FormSectionEvent} which was passed to the
* validation listener
* @param id The id of the item that is being checked. This must no
* be null.
* @throws FormProcessException if the folder already contains an item
* with the name the user provided on the input form.
* @param event the {@link FormSectionEvent} which was passed to the validation listener
* @param id The id of the item that is being checked. This must no be null.
*
* @throws FormProcessException if the folder already contains an item with the name the user
* provided on the input form.
*/
public void validateNameUniquenessWithinCategory(FormSectionEvent event,
BigDecimal id)
@ -349,8 +352,7 @@ public abstract class BasicItemForm extends FormSection
if (url == null) {
return;
}
DataQuery query =
SessionManager.getSession().retrieveQuery(
DataQuery query = SessionManager.getSession().retrieveQuery(
"com.arsdigita.categorization.getAllItemURLsForCategoryFromItem");
query.setParameter("itemID", id);
query.addEqualsFilter("lower(url)", url.toLowerCase());
@ -359,8 +361,7 @@ public abstract class BasicItemForm extends FormSection
// pending or live version of the same item
BigDecimal itemID = null;
ContentItem item =
(ContentItem) getItemSelectionModel().getSelectedObject(event.
ContentItem item = (ContentItem) getItemSelectionModel().getSelectedObject(event.
getPageState());
Collection list = getAllVersionIDs(item);
try {
@ -402,34 +403,33 @@ public abstract class BasicItemForm extends FormSection
* Adds a component to this container.
*
* @param pc the component to add to this BasicPageForm
* */
*
*/
@Override
public void add(Component pc) {
m_widgetSection.add(pc);
}
/**
* Adds a component with the specified layout constraints to this
* container. Layout constraints are defined in each layout container as
* static ints. Use a bitwise OR to specify multiple constraints.
* Adds a component with the specified layout constraints to this container. Layout constraints
* are defined in each layout container as static ints. Use a bitwise OR to specify multiple
* constraints.
*
* @param pc the component to add to this container
*
* @param constraints layout constraints (a
* bitwise OR of static ints in the particular layout)
* */
* @param constraints layout constraints (a bitwise OR of static ints in the particular layout)
*
*/
@Override
public void add(Component pc, int constraints) {
m_widgetSection.add(pc, constraints);
}
/**
* jensp, 2011-01-28
* This method can be overridden to change the label of the title field.
* To change to label of the title field can be useful for some
* content types. For example, for an organization the label "Title" for
* the field is may confusing for the normal user. For such a content type,
* the label would be changed to something like "Name of the organization".
* jensp, 2011-01-28 This method can be overridden to change the label of the title field. To
* change to label of the title field can be useful for some content types. For example, for an
* organization the label "Title" for the field is may confusing for the normal user. For such a
* content type, the label would be changed to something like "Name of the organization".
*
* @return (Content for the) Label for the title field as string
*/
@ -438,8 +438,8 @@ public abstract class BasicItemForm extends FormSection
}
/**
* Provides the text for the user hint providing some detailed information
* how to use this widget.
* Provides the text for the user hint providing some detailed information how to use this
* widget.
*
* This method can be overwritten to adjust the text for some content types.
* {@link #getTitleLabel()}
@ -451,9 +451,8 @@ public abstract class BasicItemForm extends FormSection
}
/**
* jensp, 2011-01-28
* This method does the same as {@link #getTitleLabel() } for the label of
* the name (URL) field.
* jensp, 2011-01-28 This method does the same as {@link #getTitleLabel() } for the label of the
* name (URL) field.
*
* @return (Content for the) Label for the name field as string
*/
@ -462,8 +461,8 @@ public abstract class BasicItemForm extends FormSection
}
/**
* Provides the text for the unser hint providing some detailed information
* how to use this widget.
* Provides the text for the unser hint providing some detailed information how to use this
* widget.
*
* This method can be overwritten to adjust the text for some content types.
* {@link #getNameLabel()}
@ -473,4 +472,5 @@ public abstract class BasicItemForm extends FormSection
protected GlobalizedMessage getNameHint() {
return GlobalizationUtil.globalize("cms.contenttypes.ui.name_hint");
}
}

View File

@ -28,8 +28,8 @@ import com.arsdigita.globalization.GlobalizedMessage;
import java.util.Iterator;
/**
* Displays validation errors for the page. These might have occured due to validation
* listeners on some state parameters within the page.
* Displays validation errors for the page. These might have occured due to validation listeners on
* some state parameters within the page.
*
* @author Stanislav Freidin
* @version $Id: PageErrorDisplay.java 287 2005-02-22 00:29:02Z sskracic $
@ -46,8 +46,8 @@ public class PageErrorDisplay extends List {
}
/**
* Constructs a new <code>PageErrorDisplay</code> from the errors
* supplied by a list model builder.
* Constructs a new <code>PageErrorDisplay</code> from the errors supplied by a list model
* builder.
*
* @param builder the {@link ListModelBuilder} that will supply the errors
*
@ -70,6 +70,7 @@ public class PageErrorDisplay extends List {
/**
* Gets the HTML color of the error messages.
*
* @return the HTML color of the error messages.
*/
public String getTextColor() {
@ -80,24 +81,25 @@ public class PageErrorDisplay extends List {
* Determines if there are errors to display.
*
* @param state the current page state
* @return <code>true</code> if there are any errors to display;
* <code>false</code> otherwise.
*
* @return <code>true</code> if there are any errors to display; <code>false</code> otherwise.
*/
protected boolean hasErrors(PageState state) {
return (state.getErrors().hasNext());
}
/**
* Generates the XML for this component. If the state has no errors
* in it, does not generate any XML.
* Generates the XML for this component. If the state has no errors in it, does not generate any
* XML.
*
* @param state the current page state
* @param parent the parent XML element
*/
public void generateXML(PageState state, Element parent) {
if(hasErrors(state))
if (hasErrors(state)) {
super.generateXML(state, parent);
}
}
// A private class which builds a ListModel based on form errors
private static class PageErrorModelBuilder extends LockableImpl
@ -110,6 +112,7 @@ public class PageErrorDisplay extends List {
public ListModel makeModel(List l, PageState state) {
return new StringIteratorModel(state.getErrors());
}
}
// A ListModel which generates items based on an Iterator
@ -154,14 +157,17 @@ public class PageErrorDisplay extends List {
checkState();
return Integer.toString(m_i);
}
}
// A ListCellRenderer that renders labels
private static class LabelCellRenderer implements ListCellRenderer {
public Component getComponent(List list, PageState state, Object value,
String key, int index, boolean isSelected) {
return new Label((GlobalizedMessage) value);
}
}
}

View File

@ -21,7 +21,9 @@ package com.arsdigita.search.ui;
import com.arsdigita.bebop.SimpleComponent;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.parameters.IntegerParameter;
import com.arsdigita.bebop.util.GlobalizationUtil;
import com.arsdigita.globalization.Globalization;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.kernel.Party;
import com.arsdigita.xml.Element;
@ -51,14 +53,17 @@ public class ResultsPane extends SimpleComponent {
private QueryGenerator m_query;
private IntegerParameter m_pageNumber;
private boolean m_relative;
//jensp 2014-03-04 Allow using classes to set a suitable info messages.
private GlobalizedMessage searchHelpMsg;
private GlobalizedMessage noResultsMsg;
public ResultsPane(QueryGenerator query) {
this(query, null);
}
/**
* Determines whether the links to the search results will be relative or
* absolute. The default is absolute.
* Determines whether the links to the search results will be relative or absolute. The default
* is absolute.
*/
public void setRelativeURLs(boolean relative) {
m_relative = relative;
@ -72,6 +77,14 @@ public class ResultsPane extends SimpleComponent {
m_relative = false;
}
public void setSearchHelpMsg(final GlobalizedMessage msg) {
searchHelpMsg = msg;
}
public void setNoResultsMsg(final GlobalizedMessage msg) {
noResultsMsg = msg;
}
@Override
public void generateXML(PageState state, Element parent) {
if (!m_query.hasQuery(state)) {
@ -80,8 +93,14 @@ public class ResultsPane extends SimpleComponent {
}
Element content = Search.newElement("results");
Element info = content.newChildElement("info");
if (searchHelpMsg == null) {
info.setText(
"To search for content items, please enter at least 3 letters into the search field. You can narrow the result by using additional parameters.");
} else {
//info.setText(GlobalizationUtil.globalize("cms.ui.search_help").localize().toString());
info.setText("To search for content items, please enter at least 3 letters into the search field. You can narrow the result by using additional parameters.");
info.setText(searchHelpMsg.localize().toString());
}
parent.addContent(content);
return;
}
@ -147,7 +166,11 @@ public class ResultsPane extends SimpleComponent {
Element content = Search.newElement("results");
Element info = content.newChildElement("info");
// info.setText(GlobalizationUtil.globalize("cms.ui.search_no_results").localize().toString());
if (noResultsMsg == null) {
info.setText("Sorry. Your search returned 0 results.");
} else {
info.setText(noResultsMsg.localize().toString());
}
parent.addContent(content);
}
@ -305,4 +328,5 @@ public class ResultsPane extends SimpleComponent {
return entry;
}
}

View File

@ -130,7 +130,9 @@ public class DispatcherServlet extends BaseServlet {
s_log.debug("Successfully dispatched to an application");
} else {
s_log.debug("Could not dispatch this request to an " +
"application; using the fallback servlet");
"application; sending 404");
sresp.sendError(HttpServletResponse.SC_NOT_FOUND);
/*
sreq.setAttribute(FALLING_BACK_ATTRIBUTE, Boolean.TRUE);
@ -143,6 +145,8 @@ public class DispatcherServlet extends BaseServlet {
m_dispatcher.forward(fallbackDispatcher, sreq, sresp);
DeveloperSupport.endStage("BaseDispatcher.forward");
*/
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (C) 2002-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.london.search;
import com.arsdigita.globalization.Globalized;
import com.arsdigita.globalization.GlobalizedMessage;
/**
* Compilation of methods to simplify the handling of globalizing keys.
* Basically it adds the name of package's resource bundle files to the
* globalize methods and forwards to GlobalizedMessage, shortening the
* method invocation in the various application classes.
*
* @author <a href="mailto:yon@arsdigita.com">yon@arsdigita.com</a>
* @version $Revision$ $Date$
*/
public class SearchGlobalizationUtil implements Globalized {
/** Name of Java resource files to handle CMS's globalisation. */
private static final String BUNDLE_NAME = "com.arsdigita.london.search.SearchResources";
/**
* Returns a globalized message using the package specific bundle,
* provided by BUNDLE_NAME.
*/
public static GlobalizedMessage globalize(String key) {
return new GlobalizedMessage(key, BUNDLE_NAME);
}
/**
* Returns a globalized message object, using the package specific bundle,
* as specified by BUNDLE_NAME. Also takes in an Object[] of arguments to
* interpolate into the retrieved message using the MessageFormat class.
*/
public static GlobalizedMessage globalize(String key, Object[] args) {
return new GlobalizedMessage(key, BUNDLE_NAME, args);
}
/**
* Returns the name of the package specific resource bundle.
*
* Used e.g. by com.arsdigita.cms.ui.item.ItemLanguageTable to get the
* bundle tp pass to DataTable.
*
* @return Name of resource bundle as String
*/
public static String getBundleName() {
return BUNDLE_NAME;
}
}

View File

@ -0,0 +1,7 @@
# To change this license header, choose License Headers in Project Properties.
# To change this template file, choose Tools | Templates
# and open the template in the editor.
search.ui.submit_button=Find
search.ui.help=Please enter at least three letters for a search. You may narrow the result by adding further parameters.
search.ui.no_results=No results found.

View File

@ -0,0 +1,7 @@
# To change this license header, choose License Headers in Project Properties.
# To change this template file, choose Tools | Templates
# and open the template in the editor.
search.ui.submit_button=Finden
search.ui.help=Bitte geben Sie miindestens drei Buchstaben f\u00fcr die Suche ein. Sie k\u00f6nnen das Ergebnis mit weiteren Suchparametern weiter einschr\u00e4nken.
search.ui.no_results=Keine Ergebnisse gefunden.

View File

@ -26,6 +26,7 @@ import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.parameters.BigDecimalParameter;
import com.arsdigita.cms.ui.ItemSearch;
import com.arsdigita.london.search.SearchGlobalizationUtil;
import com.arsdigita.search.ui.QueryComponent;
import com.arsdigita.search.ui.ResultsPane;
@ -49,9 +50,11 @@ public class SearchComponent extends SimpleContainer {
m_form = new Form("search", new SimpleContainer());
m_form.setMethod(Form.GET);
m_form.add(m_query);
m_form.add(new Submit("search", "Search"));
m_form.add(new Submit("search", SearchGlobalizationUtil.globalize("search.ui.submit_button")));
m_results = new ResultsPane(query, engine);
m_results.setSearchHelpMsg(SearchGlobalizationUtil.globalize("search.ui.help"));
m_results.setNoResultsMsg(SearchGlobalizationUtil.globalize("search.ui.no_results"));
add(m_form);