SlideShare ist ein Scribd-Unternehmen logo
1 von 54
Downloaden Sie, um offline zu lesen
Daniel Seidel – Alkacon Software GmbH
Advanced searching
29.09.2015
2
What can you expect?
Presentation of new
OpenCms features
A tutorial on advanced Solr
features
3
A short history on searching
OpenCms 6.0
● Simple server-side search
● Many uni-lingual indexes
● Many proprietary configuration options
OpenCms 8.5
● Many more features
● Facets
● Highlighting
● Did you mean?
● …
● Multilingual indexes
● Support for client-side searches?
4
Building a search page - Lucene
How to
● Configure your index (one per language)
● Write JSP using CmsSearch as bean
Pros and Cons
Easily produce a search page
Easy query options, incl. simple filter and sort options
Pagination support
Scriptlet code necessary
All server-side code
Index configuration necessary (for each language)
No support for facets etc.
5
Building a search page - Solr
How to
● Write a custom client side search (using GWT)
● Adjust the demo search (may include altering GWT code)
Pros and Cons
Great search experience possible
All Ajax based
Many great features: facets, auto-completion, “Did you mean?”
“unlimited” sorting options
Relies heavily on JavaScript
Very complex to build and adjust
State keeping
Html rendering with JavaScript
Nearly always a per-customer solution
6
Combining the Advantages
Simplicity
since 6.0
Many features
since 8.5
● Stay on the server side (JSP)
● Class like CmsSearch, but
● Expose more Solr features
● Usable without scriptlet code
Design questions
7
What is the value of CmsSearch?
Simple search API tailored for OpenCms
Managing state
Hiding search details
Mapping from request parameters to
search options
Design questions
8
What can we support for Solr?
Simple search API tailored for OpenCms
Managing state
Mapping from request parameters to
search options
Hiding all search details
Design questions
9
How can we ease usage?
Reduce configuration to a minimal
Avoid explicit bean initialization
Allow to add raw Solr query parts
Easy access to results, state, configuration
(no scriptlet code necessary)
● Via search you obtain
● Configuration
● State (current query, checked facet entries, ...)
● Results (search results, facet items, ...)
● Via configFile a special XML content is given
● You drag search form configurations on the page
to render a fully functional search form
● A “feature-complete” default formatter is provided
10
The new tag: <cms:search>
<cms:search var="search"
configFile="${content.filename}"/>
● Live Demo
Drag & Drop your search form
Demo
Demo Demo
Demo
デモ
Search form creation
● Request parameters
● In cases where the default causes collisions
● In cases where additional parameters should be
handled
● General search options
● Core / Index
● Search for empty query?
● Escape query string?
● Query string modifier
● Add additional query parameters
12
What can I configure? (I)
● Special search options
● Pagination
● Sorting
● Facets (field and query facets)
● Highlighting
● Did you mean?
13
What can I configure? (II)
Important
You can, but need not necessarily
configure everything!
I_CmsSearchResultWrapper
I_CmsSearchControllerMain
Single controllers with
configuration and state
Result information
Results list
Facets result
Highlighting result
Page info
...
I_CmsSearchStateParameters
14
Structure of the result object
Configure the UI
elements
(input field names
and current
state/value)
Print results,
facet items,
etc.
Create a suitable link
that contains the
complete state of the
search form
<!-- ... -->
<c:set var="controllers" value="${search.controller}"/>
<!-- ... -->
<c:set var="sort" value="${controllers.sorting}"/>
<!-- ... -->
<select name="${sort.config.sortParam}">
<c:forEach var="option"
items="${sort.config.sortOptions}">
<option value="${option.paramValue}"
${sort.state.checkSelected[option]?"selected":""}>
${option.label}
</option>
</c:forEach>
</select>
<!-- ... -->
15
Rendering example: Sort options
<!-- ... -->
<c:set var="controllers" value="${search.controller}"/>
<!-- ... -->
<c:set var="sort" value="${controllers.sorting}"/>
<!-- ... -->
<select name="${sort.config.sortParam}">
<c:forEach var="option"
items="${sort.config.sortOptions}">
<option value="${option.paramValue}"
${sort.state.checkSelected[option]?"selected":""}>
${option.label}
</option>
</c:forEach>
</select>
<!-- ... -->
16
Rendering example: Sort options
Use abbreviations
<!-- ... -->
<c:set var="controllers" value="${search.controller}"/>
<!-- ... -->
<c:set var="sort" value="${controllers.sorting}"/>
<!-- ... -->
<select name="${sort.config.sortParam}">
<c:forEach var="option"
items="${sort.config.sortOptions}">
<option value="${option.paramValue}"
${sort.state.checkSelected[option]?"selected":""}>
${option.label}
</option>
</c:forEach>
</select>
<!-- ... -->
17
Rendering example: Sort options
Use the configuration
<!-- ... -->
<c:set var="controllers" value="${search.controller}"/>
<!-- ... -->
<c:set var="sort" value="${controllers.sorting}"/>
<!-- ... -->
<select name="${sort.config.sortParam}">
<c:forEach var="option"
items="${sort.config.sortOptions}">
<option value="${option.paramValue}"
${sort.state.checkSelected[option]?"selected":""}>
${option.label}
</option>
</c:forEach>
</select>
<!-- ... -->
18
Rendering example: Sort options
Use the state
<!-- ... -->
<c:forEach var="searchResult" items="${search.searchResults}">
<a href='<cms:link>${searchResult.fields["path"]}</cms:link>'>
${searchResult.fields["Title_prop"]}
</a>
<p>
${cms:trimToSize(
fn:escapeXml(searchResult.fields["content_en"])
,250)}
</p>
<hr />
</c:forEach>
<!-- ... -->
19
Rendering example: Results
<!-- ... -->
<c:forEach var="searchResult" items="${search.searchResults}">
<a href='<cms:link>${searchResult.fields["path"]}</cms:link>'>
${searchResult.fields["Title_prop"]}
</a>
<p>
${cms:trimToSize(
fn:escapeXml(searchResult.fields["content_en"])
,250)}
</p>
<hr />
</c:forEach>
<!-- ... -->
20
Rendering example: Results
Loop over the result collection
(get I_CmsSearchResourceBean objects)
<!-- ... -->
<c:forEach var="searchResult" items="${search.searchResults}">
<a href='<cms:link>${searchResult.fields["path"]}</cms:link>'>
${searchResult.fields["Title_prop"]}
</a>
<p>
${cms:trimToSize(
fn:escapeXml(searchResult.fields["content_en"])
,250)}
</p>
<hr />
</c:forEach>
<!-- ... -->
21
Rendering example: Results
Access index fields
<!-- ... -->
<c:set var="fControllers"
value="${controllers.fieldFacets}"/>
<c:forEach var="facet" items="${search.fieldFacets}">
<c:set var="facetController"
value="${fControllers.fieldFacetController[facet.name]}"/>
<c:if test="${cms:getListSize(facet.values) > 0}">
<!-- Render facet – see next slide -->
</c:if>
</c:forEach>
<!-- ... -->
22
Rendering example: Facets (I)
<!-- ... -->
<c:set var="fControllers"
value="${controllers.fieldFacets}"/>
<c:forEach var="facet" items="${search.fieldFacets}">
<c:set var="facetController"
value="${fControllers.fieldFacetController[facet.name]}"/>
<c:if test="${cms:getListSize(facet.values) > 0}">
<!-- Render facet – see next slide -->
</c:if>
</c:forEach>
<!-- ... -->
23
Rendering example: Facets (I)
Loop over facets from the
search result
<!-- ... -->
<c:set var="fControllers"
value="${controllers.fieldFacets}"/>
<c:forEach var="facet" items="${search.fieldFacets}">
<c:set var="facetController"
value="${fControllers.fieldFacetController[facet.name]}"/>
<c:if test="${cms:getListSize(facet.values) > 0}">
<!-- Render facet – see next slide -->
</c:if>
</c:forEach>
<!-- ... -->
24
Rendering example: Facets (I)
Get the facet’s controller
<!-- ... -->
<c:set var="fControllers"
value="${controllers.fieldFacets}"/>
<c:forEach var="facet" items="${search.fieldFacets}">
<c:set var="facetController"
value="${fControllers.fieldFacetController[facet.name]}"/>
<c:if test="${cms:getListSize(facet.values) > 0}">
<!-- Render facet – see next slide -->
</c:if>
</c:forEach>
<!-- ... -->
25
Rendering example: Facets (I)
Render the facet if necessary
(see next slide)
<!-- ... -->
<div>${facetController.config.label}</div>
<c:forEach var="facetItem" items="${facet.values}">
<div class="checkbox">
<label>
<input type="checkbox"
name="${facetController.config.paramKey}"
value="${facetItem.name}"
${facetController.state.isChecked[facetItem.name]
?"checked":""} />
${facetItem.name} (${facetItem.count})
</label>
</div>
</c:forEach>
<!-- ... -->
26
Rendering example: Facets (II)
<!-- ... -->
<div>${facetController.config.label}</div>
<c:forEach var="facetItem" items="${facet.values}">
<div class="checkbox">
<label>
<input type="checkbox"
name="${facetController.config.paramKey}"
value="${facetItem.name}"
${facetController.state.isChecked[facetItem.name]
?"checked":""} />
${facetItem.name} (${facetItem.count})
</label>
</div>
</c:forEach>
<!-- ... -->
27
Rendering example: Facets (II)
Use the configuration
<!-- ... -->
<div>${facetController.config.label}</div>
<c:forEach var="facetItem" items="${facet.values}">
<div class="checkbox">
<label>
<input type="checkbox"
name="${facetController.config.paramKey}"
value="${facetItem.name}"
${facetController.state.isChecked[facetItem.name]
?"checked":""} />
${facetItem.name} (${facetItem.count})
</label>
</div>
</c:forEach>
<!-- ... -->
28
Rendering example: Facets (II)
Use the result
<!-- ... -->
<div>${facetController.config.label}</div>
<c:forEach var="facetItem" items="${facet.values}">
<div class="checkbox">
<label>
<input type="checkbox"
name="${facetController.config.paramKey}"
value="${facetItem.name}"
${facetController.state.isChecked[facetItem.name]
?"checked":""} />
${facetItem.name} (${facetItem.count})
</label>
</div>
</c:forEach>
<!-- ... -->
29
Rendering example: Facets (II)
Use the state
<c:set var="pagination" value="${controllers.pagination}"/>
<c:forEach var="i" begin="${search.pageNavFirst}"
end="${search.pageNavLast}">
<c:set var="is">${i}</c:set>
<li ${pagination.state.currentPage eq i ? "class='active'" : ""}>
<a href="<cms:link>${cms.requestContext.uri}
?${search.stateParameters.setPage[is]}
</cms:link>">${is}</a>
</li>
</c:forEach>
<li>
<c:set var="pages">${search.numPages}</c:set>
<a href="<cms:link>${cms.requestContext.uri}
?${search.stateParameters.setPage[pages]}
</cms:link>">Last</a>
</li>
30
Rendering example: Pagination
<c:set var="pagination" value="${controllers.pagination}"/>
<c:forEach var="i" begin="${search.pageNavFirst}"
end="${search.pageNavLast}">
<c:set var="is">${i}</c:set>
<li ${pagination.state.currentPage eq i ? "class='active'" : ""}>
<a href="<cms:link>${cms.requestContext.uri}
?${search.stateParameters.setPage[is]}
</cms:link>">${is}</a>
</li>
</c:forEach>
<li>
<c:set var="pages">${search.numPages}</c:set>
<a href="<cms:link>${cms.requestContext.uri}
?${search.stateParameters.setPage[pages]}
</cms:link>">Last</a>
</li>
31
Rendering example: Pagination
Use pagination support
<c:set var="pagination" value="${controllers.pagination}"/>
<c:forEach var="i" begin="${search.pageNavFirst}"
end="${search.pageNavLast}">
<c:set var="is">${i}</c:set>
<li ${pagination.state.currentPage eq i ? "class='active'" : ""}>
<a href="<cms:link>${cms.requestContext.uri}
?${search.stateParameters.setPage[is]}
</cms:link>">${is}</a>
</li>
</c:forEach>
<li>
<c:set var="pages">${search.numPages}</c:set>
<a href="<cms:link>${cms.requestContext.uri}
?${search.stateParameters.setPage[pages]}
</cms:link>">Last</a>
</li>
32
Rendering example: Pagination
Use current state
<c:set var="pagination" value="${controllers.pagination}"/>
<c:forEach var="i" begin="${search.pageNavFirst}"
end="${search.pageNavLast}">
<c:set var="is">${i}</c:set>
<li ${pagination.state.currentPage eq i ? "class='active'" : ""}>
<a href="<cms:link>${cms.requestContext.uri}
?${search.stateParameters.setPage[is]}
</cms:link>">${is}</a>
</li>
</c:forEach>
<li>
<c:set var="pages">${search.numPages}</c:set>
<a href="<cms:link>${cms.requestContext.uri}
?${search.stateParameters.setPage[pages]}
</cms:link>">Last</a>
</li>
33
Rendering example: Pagination
Use state parameters
● Two options to send the current state:
● Submit a form
● Use state parameters
● With state parameters
● Everything is manipulated explicitly
● You do not need a form at all
● With a form
● You must make sure to send all the state you want
(use hidden parameters, e.g., for the last query)
● You can intentionally prevent state transmission
(e.g., for the current page)
34
Form vs. state parameters
● We did
● Introduce the tag <cms:search>
● See its configuration via an XML content
● Explore how to write a formatter for a search form
● If you need more information on formatting
● Explore the default formatter
● Explore the classes under
org.opencms.jsp.search.result
● We did not
● Cover all configuration options
● See all use cases for <cms:search>
35
Short summary
● Intention
● Show blogs, news, ...
● Link to detail pages
● Realization
● <cms:contentload>
● Manifold collectors
● Question
● Where’s the
difference between
lists and a search
result page?
36
Lists in OpenCms
● Intention
● Show blogs, news, ...
● Link to detail pages
● Realization
● <cms:contentload>
● Manifold collectors
● Question
● Where’s the
difference between
lists and a search
result page?
37
Lists in OpenCms
Essentially, there is no
difference!
38
A short history of lists
● Simple way to render lists
● Many specific collectors
● Facility to edit list entries directly
OpenCms 6.0 <cms:contentload> is introduced
OpenCms 8.5
● Collecting “byQuery” or “byContext”
● First contact of Search and Lists
● No facets etc. supported
CmsSolrCollector is added
OpenCms 10 <cms:search> and <cms:edit> are introduced
● Lists and search become one
● Facets etc. available for lists
● Editing becomes decoupled from lists
?
● What is specific for a list?
● XML content for configuration is unsuitable
● There is no query string provided by the user
● Usually there is no form
● XML contents, not the index is accessed
● How does <cms:search> handle the pecularities
● Configuration via JSON (String or file)
● An option to ignore the query parameter
● The already seen state parameters
(no form is necessary)
● I_CmsSearchResourceBean allows to access XML
contents via the CmsJspContentAccessBean
39
Lists with <cms:search>
● Live Demo
Watch out for the Solr features
Demo
Demo Demo
Demo
デモ
A list with <cms:search>
<c:set var="searchConfig">
{ "ignorequery" : true,
"extrasolrparams" :
"fq=type:u-blog&fq=parent-folders:
"/sites/default/.content/blogentries/"",
"pagesize" : ${content.value.pageSize},
"pagenavlength" : ${cms.element.settings["navlength"]}
<!-- Facet and sort option configuration -->
}
</c:set>
<cms:search configString="${searchConfig}" var="search"/>
<!-- ... -->
41
The JSON configuration for a list
<c:set var="searchConfig">
{ "ignorequery" : true,
"extrasolrparams" :
"fq=type:u-blog&fq=parent-folders:
"/sites/default/.content/blogentries/"",
"pagesize" : ${content.value.pageSize},
"pagenavlength" : ${cms.element.settings["navlength"]}
<!-- Facet and sort option configuration -->
}
</c:set>
<cms:search configString="${searchConfig}" var="search"/>
<!-- ... -->
42
The JSON configuration for a list
Most important options
<c:set var="searchConfig">
{ "ignorequery" : true,
"extrasolrparams" :
"fq=type:u-blog&fq=parent-folders:
"/sites/default/.content/blogentries/"",
"pagesize" : ${content.value.pageSize},
"pagenavlength" : ${cms.element.settings["navlength"]}
<!-- Facet and sort option configuration -->
}
</c:set>
<cms:search configString="${searchConfig}" var="search"/>
<!-- ... -->
43
The JSON configuration for a list
Optional extra features
<c:set var="searchConfig">
{ "ignorequery" : true,
"extrasolrparams" :
"fq=type:u-blog&fq=parent-folders:
"/sites/default/.content/blogentries/"",
"pagesize" : ${content.value.pageSize},
"pagenavlength" : ${cms.element.settings["navlength"]}
<!-- Facet and sort option configuration -->
}
</c:set>
<cms:search configString="${searchConfig}" var="search"/>
<!-- ... -->
44
The JSON configuration for a list
The content adjusts the configuration
<c:choose>
<c:when test="${search.numFound > 0}">
<c:forEach var="result" items="${search.searchResults}">
<c:set var="content" value="${result.xmlContent}"/>
<!-- render entry as usual -->
</c:forEach>
</c:when>
<c:otherwise>
No results found.
</c:otherwise>
</c:choose>
45
Rendering the list entries
Easier than before
Getting results and iterating over
them is separated
No nested <cms:contentload>
anymore
● <cms:contentload> supported
● Editing, adding or deleting list entries
● Adding entries to an empty list
● Can we provide the same feature?
● No, because iteration is separated from <cms:search>
● Do we need the same feature?
● No, there’s no reason why edit options and content
loading has to be coupled
● Can we get similar edit options differently?
● Yes, a special <cms:edit> tag
46
Editing list entries
● Places edit points wherever you like
● Allows to edit or delete existing XML contents
● Allows to add new contents
● Highlights the enclosed HTML when hovering
over the edit point
● New contents can be placed
● At the place configured in the sitemap configuration
● In a provided folder
● Where the content that is edited is located
47
The tag <cms:edit>
<c:choose>
<c:when test="${search.numFound > 0}">
<c:forEach var="result" items="${search.searchResults}">
<c:set var="content" value="${result.xmlContent}"/>
<cms:edit uuid='${result.fields["id"]}'
create="true" delete="true">
<!-- render entry as usual -->
</cms:edit>
</c:forEach>
</c:when>
<c:otherwise>
<cms:edit createType="u-blog">
<div>No results found.</div>
</cms:edit>
</c:otherwise>
</c:choose>
48
Edit options for the list
Easier than before
Harmonized usage for empty
and non-empty list
● How about the “Publish this page” option?
● <cms:contentload> with attribute “editable”
causes list entries to be related to the page
● Do we have a similar mechanism?
● Using <cms:edit> the edited content becomes
related to the page
● But does this suffice?
● Not if we use pagination.
● So can we do better?
● Yes: <cms:search ... addContentInfo="true">
● All list entries become related to the page
49
Do we still miss a feature?
50
What should you remember?
Server-sided Solr search becomes easy
Search pages and lists become the same
Edit point needed: Use <cms:edit>
By, by <cms:contentload> and friends
● Containers in lists
● Container tag takes the element(s)
<cms:container ... elements="${uuid}"/>
● Rendering is done by a suitable formatter
51
What’s next? (Maybe)
Easily render contents of different types
Inline editing will work out of the box
Harmonized rendering of XML contents
● Containers in lists
● Container tag takes the element(s)
<cms:container ... elements="${uuid}"/>
● Rendering is done by a suitable formatter
52
What’s next? (Maybe)
Easily render contents of different types
Inline editing will work out of the box
Harmonized rendering of XML contents
53
Last comments
Solr updated to version 5.1
(further updates follow)
Gallery index replaced by “Solr offline”
(watch out for bugs)
This is OpenCms 10 Alpha 1
(don’t expect everything in the final state)
Daniel Seidel
Alkacon Software GmbH
http://www.alkacon.com
http://www.opencms.org
Thank you very much for your attention!

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (20)

ECMA Script
ECMA ScriptECMA Script
ECMA Script
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
 
MongoDB Replica Sets
MongoDB Replica SetsMongoDB Replica Sets
MongoDB Replica Sets
 
Deep dive to PostgreSQL Indexes
Deep dive to PostgreSQL IndexesDeep dive to PostgreSQL Indexes
Deep dive to PostgreSQL Indexes
 
An introduction to MongoDB
An introduction to MongoDBAn introduction to MongoDB
An introduction to MongoDB
 
Functional programming with Java 8
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8
 
Web forms in ASP.net
Web forms in ASP.netWeb forms in ASP.net
Web forms in ASP.net
 
Histograms in MariaDB, MySQL and PostgreSQL
Histograms in MariaDB, MySQL and PostgreSQLHistograms in MariaDB, MySQL and PostgreSQL
Histograms in MariaDB, MySQL and PostgreSQL
 
Offzone | Another waf bypass
Offzone | Another waf bypassOffzone | Another waf bypass
Offzone | Another waf bypass
 
E-Commerce search with Elasticsearch
E-Commerce search with ElasticsearchE-Commerce search with Elasticsearch
E-Commerce search with Elasticsearch
 
MongoDB Schema Design: Practical Applications and Implications
MongoDB Schema Design: Practical Applications and ImplicationsMongoDB Schema Design: Practical Applications and Implications
MongoDB Schema Design: Practical Applications and Implications
 
Web Worker, Service Worker and Worklets
Web Worker, Service Worker and WorkletsWeb Worker, Service Worker and Worklets
Web Worker, Service Worker and Worklets
 
InnoDB Locking Explained with Stick Figures
InnoDB Locking Explained with Stick FiguresInnoDB Locking Explained with Stick Figures
InnoDB Locking Explained with Stick Figures
 
Javascript
JavascriptJavascript
Javascript
 
Reverse Engineering Malicious Javascript
Reverse Engineering Malicious JavascriptReverse Engineering Malicious Javascript
Reverse Engineering Malicious Javascript
 
Asp.net MVC training session
Asp.net MVC training sessionAsp.net MVC training session
Asp.net MVC training session
 
Monitoramento de Banco de dados SQL Server com Zabbix
Monitoramento de Banco de dados SQL Server com ZabbixMonitoramento de Banco de dados SQL Server com Zabbix
Monitoramento de Banco de dados SQL Server com Zabbix
 
OpenSIPS Workshop
OpenSIPS WorkshopOpenSIPS Workshop
OpenSIPS Workshop
 
Mongo DB 완벽가이드 - 4장 쿼리하기
Mongo DB 완벽가이드 - 4장 쿼리하기Mongo DB 완벽가이드 - 4장 쿼리하기
Mongo DB 완벽가이드 - 4장 쿼리하기
 
스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해
 

Andere mochten auch

Andere mochten auch (11)

OpenCms Days 2015 OCEE explained
OpenCms Days 2015 OCEE explainedOpenCms Days 2015 OCEE explained
OpenCms Days 2015 OCEE explained
 
OpenCms Days 2015 Workflow using Docker and Jenkins
OpenCms Days 2015 Workflow using Docker and JenkinsOpenCms Days 2015 Workflow using Docker and Jenkins
OpenCms Days 2015 Workflow using Docker and Jenkins
 
OpenCms Days 2016: OpenCms at the swiss seismological service
OpenCms Days 2016: OpenCms at the swiss seismological serviceOpenCms Days 2016: OpenCms at the swiss seismological service
OpenCms Days 2016: OpenCms at the swiss seismological service
 
OpenCms Days 2016: Participation and transparency portals with OpenCms
OpenCms Days 2016: Participation and transparency portals with OpenCmsOpenCms Days 2016: Participation and transparency portals with OpenCms
OpenCms Days 2016: Participation and transparency portals with OpenCms
 
OpenCms Days 2015 OpenCms X marks the spot
OpenCms Days 2015 OpenCms X marks the spotOpenCms Days 2015 OpenCms X marks the spot
OpenCms Days 2015 OpenCms X marks the spot
 
OpenCms Days 2015 Creating Apps for the OpenCms 10 workplace
OpenCms Days 2015  Creating Apps for the OpenCms 10 workplace OpenCms Days 2015  Creating Apps for the OpenCms 10 workplace
OpenCms Days 2015 Creating Apps for the OpenCms 10 workplace
 
OpenCms Days 2015 Next generation repository
OpenCms Days 2015  Next generation repositoryOpenCms Days 2015  Next generation repository
OpenCms Days 2015 Next generation repository
 
OpenCms Days 2015 Modern templates with nested containers
OpenCms Days 2015 Modern templates with nested containersOpenCms Days 2015 Modern templates with nested containers
OpenCms Days 2015 Modern templates with nested containers
 
OpenCms Days 2016: Keynote - Introducing OpenCms 10.5
OpenCms Days 2016:   Keynote - Introducing OpenCms 10.5OpenCms Days 2016:   Keynote - Introducing OpenCms 10.5
OpenCms Days 2016: Keynote - Introducing OpenCms 10.5
 
OpenCms Days 2016: Multilingual websites with OpenCms
OpenCms Days 2016:   Multilingual websites with OpenCmsOpenCms Days 2016:   Multilingual websites with OpenCms
OpenCms Days 2016: Multilingual websites with OpenCms
 
OpenCms Days 2016: Next generation content repository
OpenCms Days 2016: Next generation content repository OpenCms Days 2016: Next generation content repository
OpenCms Days 2016: Next generation content repository
 

Ähnlich wie OpenCms Days 2015 Advanced Solr Searching

SharePoint Cincy 2012 - jQuery essentials
SharePoint Cincy 2012 - jQuery essentialsSharePoint Cincy 2012 - jQuery essentials
SharePoint Cincy 2012 - jQuery essentials
Mark Rackley
 
MVC & SQL_In_1_Hour
MVC & SQL_In_1_HourMVC & SQL_In_1_Hour
MVC & SQL_In_1_Hour
Dilip Patel
 
Drupal 8. Search API. Facets. Customize / combine facets
Drupal 8. Search API. Facets. Customize / combine facetsDrupal 8. Search API. Facets. Customize / combine facets
Drupal 8. Search API. Facets. Customize / combine facets
AnyforSoft
 
Google
GoogleGoogle
Google
soon
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 

Ähnlich wie OpenCms Days 2015 Advanced Solr Searching (20)

Using Search API, Search API Solr and Facets in Drupal 8
Using Search API, Search API Solr and Facets in Drupal 8Using Search API, Search API Solr and Facets in Drupal 8
Using Search API, Search API Solr and Facets in Drupal 8
 
Harness SharePoint and jQuery to Make Dynamic Displays and Applications
 Harness SharePoint and jQuery to Make Dynamic Displays and Applications Harness SharePoint and jQuery to Make Dynamic Displays and Applications
Harness SharePoint and jQuery to Make Dynamic Displays and Applications
 
SharePoint Cincy 2012 - jQuery essentials
SharePoint Cincy 2012 - jQuery essentialsSharePoint Cincy 2012 - jQuery essentials
SharePoint Cincy 2012 - jQuery essentials
 
MVC & SQL_In_1_Hour
MVC & SQL_In_1_HourMVC & SQL_In_1_Hour
MVC & SQL_In_1_Hour
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
IGears: Template Architecture and Principles
IGears: Template Architecture and PrinciplesIGears: Template Architecture and Principles
IGears: Template Architecture and Principles
 
SharePoint and jQuery Essentials
SharePoint and jQuery EssentialsSharePoint and jQuery Essentials
SharePoint and jQuery Essentials
 
How to generate customized java 8 code from your database
How to generate customized java 8 code from your databaseHow to generate customized java 8 code from your database
How to generate customized java 8 code from your database
 
Silicon Valley JUG - How to generate customized java 8 code from your database
Silicon Valley JUG - How to generate customized java 8 code from your databaseSilicon Valley JUG - How to generate customized java 8 code from your database
Silicon Valley JUG - How to generate customized java 8 code from your database
 
Develop an App with the Odoo Framework
Develop an App with the Odoo FrameworkDevelop an App with the Odoo Framework
Develop an App with the Odoo Framework
 
Drupal 8. Search API. Facets. Customize / combine facets
Drupal 8. Search API. Facets. Customize / combine facetsDrupal 8. Search API. Facets. Customize / combine facets
Drupal 8. Search API. Facets. Customize / combine facets
 
Google
GoogleGoogle
Google
 
Becoming "Facet"-nated with Search API
Becoming "Facet"-nated with Search APIBecoming "Facet"-nated with Search API
Becoming "Facet"-nated with Search API
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Leveraging SharePoint 2013 Search and CSR
Leveraging SharePoint 2013 Search and CSRLeveraging SharePoint 2013 Search and CSR
Leveraging SharePoint 2013 Search and CSR
 
Jsf2.0 -4
Jsf2.0 -4Jsf2.0 -4
Jsf2.0 -4
 
The SharePoint & jQuery Guide
The SharePoint & jQuery GuideThe SharePoint & jQuery Guide
The SharePoint & jQuery Guide
 
The SharePoint and jQuery Guide by Mark Rackley - SPTechCon
The SharePoint and jQuery Guide by Mark Rackley - SPTechConThe SharePoint and jQuery Guide by Mark Rackley - SPTechCon
The SharePoint and jQuery Guide by Mark Rackley - SPTechCon
 
Agile data presentation 3 - cambridge
Agile data   presentation 3 - cambridgeAgile data   presentation 3 - cambridge
Agile data presentation 3 - cambridge
 
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.jsDrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
 

Mehr von Alkacon Software GmbH & Co. KG

Mehr von Alkacon Software GmbH & Co. KG (18)

OpenCms Days 2015 OpenGovernment
OpenCms Days 2015 OpenGovernmentOpenCms Days 2015 OpenGovernment
OpenCms Days 2015 OpenGovernment
 
OpenCms Days 2015 OpenCms at erarta
OpenCms Days 2015 OpenCms at erarta OpenCms Days 2015 OpenCms at erarta
OpenCms Days 2015 OpenCms at erarta
 
OpenCms Days 2015 How do you develop for OpenCms?
OpenCms Days 2015 How do you develop for OpenCms?OpenCms Days 2015 How do you develop for OpenCms?
OpenCms Days 2015 How do you develop for OpenCms?
 
OpenCms Days 2015 Arkema, a leading chemicals company
OpenCms Days 2015 Arkema, a leading chemicals companyOpenCms Days 2015 Arkema, a leading chemicals company
OpenCms Days 2015 Arkema, a leading chemicals company
 
OpenCms Days 2014 - How Techem handles international customer portals
OpenCms Days 2014 - How Techem handles international customer portalsOpenCms Days 2014 - How Techem handles international customer portals
OpenCms Days 2014 - How Techem handles international customer portals
 
OpenCms Days 2014 - Enhancing OpenCms front end development with Sass and Grunt
OpenCms Days 2014 - Enhancing OpenCms front end development with Sass and GruntOpenCms Days 2014 - Enhancing OpenCms front end development with Sass and Grunt
OpenCms Days 2014 - Enhancing OpenCms front end development with Sass and Grunt
 
OpenCms Days 2014 - OpenCms cloud setup with the FI-TS
OpenCms Days 2014 - OpenCms cloud setup with the FI-TSOpenCms Days 2014 - OpenCms cloud setup with the FI-TS
OpenCms Days 2014 - OpenCms cloud setup with the FI-TS
 
OpenCms Days 2014 - OpenCms Module Development and Deployment with IntelliJ, ...
OpenCms Days 2014 - OpenCms Module Development and Deployment with IntelliJ, ...OpenCms Days 2014 - OpenCms Module Development and Deployment with IntelliJ, ...
OpenCms Days 2014 - OpenCms Module Development and Deployment with IntelliJ, ...
 
OpenCms Days 2014 - OpenCms 9 - A video tube?
OpenCms Days 2014 - OpenCms 9 - A video tube?OpenCms Days 2014 - OpenCms 9 - A video tube?
OpenCms Days 2014 - OpenCms 9 - A video tube?
 
OpenCms Days 2014 - User Generated Content in OpenCms 9.5
OpenCms Days 2014 - User Generated Content in OpenCms 9.5OpenCms Days 2014 - User Generated Content in OpenCms 9.5
OpenCms Days 2014 - User Generated Content in OpenCms 9.5
 
OpenCms Days 2014 - Updating to OpenCms 9.5
OpenCms Days 2014 - Updating to OpenCms 9.5OpenCms Days 2014 - Updating to OpenCms 9.5
OpenCms Days 2014 - Updating to OpenCms 9.5
 
OpenCms Days 2014 - Using the SOLR collector
OpenCms Days 2014 - Using the SOLR collectorOpenCms Days 2014 - Using the SOLR collector
OpenCms Days 2014 - Using the SOLR collector
 
OpenCms Days 2014 - Responsive bootstrap templates reloaded
OpenCms Days 2014 - Responsive bootstrap templates reloadedOpenCms Days 2014 - Responsive bootstrap templates reloaded
OpenCms Days 2014 - Responsive bootstrap templates reloaded
 
OpenCms Days 2014 - Nested containers in action
OpenCms Days 2014 - Nested containers in actionOpenCms Days 2014 - Nested containers in action
OpenCms Days 2014 - Nested containers in action
 
OpenCms Days 2014 Keynote - Step up to OpenCms 9.5
OpenCms Days 2014 Keynote - Step up to OpenCms 9.5OpenCms Days 2014 Keynote - Step up to OpenCms 9.5
OpenCms Days 2014 Keynote - Step up to OpenCms 9.5
 
OpenCms Days 2014 - Introducing the 9.5 OpenCms documentation
OpenCms Days 2014 - Introducing the 9.5 OpenCms documentationOpenCms Days 2014 - Introducing the 9.5 OpenCms documentation
OpenCms Days 2014 - Introducing the 9.5 OpenCms documentation
 
OpenCms Days 2014 - OpenCms content editor and pdf extensions
OpenCms Days 2014 - OpenCms content editor and pdf extensionsOpenCms Days 2014 - OpenCms content editor and pdf extensions
OpenCms Days 2014 - OpenCms content editor and pdf extensions
 
Open cms days 2013 - all dressed up_release
Open cms days 2013 - all dressed up_releaseOpen cms days 2013 - all dressed up_release
Open cms days 2013 - all dressed up_release
 

Kürzlich hochgeladen

%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
masabamasaba
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
chiefasafspells
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 

Kürzlich hochgeladen (20)

Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
Abortion Pills In Pretoria ](+27832195400*)[ 🏥 Women's Abortion Clinic In Pre...
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 

OpenCms Days 2015 Advanced Solr Searching

  • 1. Daniel Seidel – Alkacon Software GmbH Advanced searching 29.09.2015
  • 2. 2 What can you expect? Presentation of new OpenCms features A tutorial on advanced Solr features
  • 3. 3 A short history on searching OpenCms 6.0 ● Simple server-side search ● Many uni-lingual indexes ● Many proprietary configuration options OpenCms 8.5 ● Many more features ● Facets ● Highlighting ● Did you mean? ● … ● Multilingual indexes ● Support for client-side searches?
  • 4. 4 Building a search page - Lucene How to ● Configure your index (one per language) ● Write JSP using CmsSearch as bean Pros and Cons Easily produce a search page Easy query options, incl. simple filter and sort options Pagination support Scriptlet code necessary All server-side code Index configuration necessary (for each language) No support for facets etc.
  • 5. 5 Building a search page - Solr How to ● Write a custom client side search (using GWT) ● Adjust the demo search (may include altering GWT code) Pros and Cons Great search experience possible All Ajax based Many great features: facets, auto-completion, “Did you mean?” “unlimited” sorting options Relies heavily on JavaScript Very complex to build and adjust State keeping Html rendering with JavaScript Nearly always a per-customer solution
  • 6. 6 Combining the Advantages Simplicity since 6.0 Many features since 8.5 ● Stay on the server side (JSP) ● Class like CmsSearch, but ● Expose more Solr features ● Usable without scriptlet code
  • 7. Design questions 7 What is the value of CmsSearch? Simple search API tailored for OpenCms Managing state Hiding search details Mapping from request parameters to search options
  • 8. Design questions 8 What can we support for Solr? Simple search API tailored for OpenCms Managing state Mapping from request parameters to search options Hiding all search details
  • 9. Design questions 9 How can we ease usage? Reduce configuration to a minimal Avoid explicit bean initialization Allow to add raw Solr query parts Easy access to results, state, configuration (no scriptlet code necessary)
  • 10. ● Via search you obtain ● Configuration ● State (current query, checked facet entries, ...) ● Results (search results, facet items, ...) ● Via configFile a special XML content is given ● You drag search form configurations on the page to render a fully functional search form ● A “feature-complete” default formatter is provided 10 The new tag: <cms:search> <cms:search var="search" configFile="${content.filename}"/>
  • 11. ● Live Demo Drag & Drop your search form Demo Demo Demo Demo デモ Search form creation
  • 12. ● Request parameters ● In cases where the default causes collisions ● In cases where additional parameters should be handled ● General search options ● Core / Index ● Search for empty query? ● Escape query string? ● Query string modifier ● Add additional query parameters 12 What can I configure? (I)
  • 13. ● Special search options ● Pagination ● Sorting ● Facets (field and query facets) ● Highlighting ● Did you mean? 13 What can I configure? (II) Important You can, but need not necessarily configure everything!
  • 14. I_CmsSearchResultWrapper I_CmsSearchControllerMain Single controllers with configuration and state Result information Results list Facets result Highlighting result Page info ... I_CmsSearchStateParameters 14 Structure of the result object Configure the UI elements (input field names and current state/value) Print results, facet items, etc. Create a suitable link that contains the complete state of the search form
  • 15. <!-- ... --> <c:set var="controllers" value="${search.controller}"/> <!-- ... --> <c:set var="sort" value="${controllers.sorting}"/> <!-- ... --> <select name="${sort.config.sortParam}"> <c:forEach var="option" items="${sort.config.sortOptions}"> <option value="${option.paramValue}" ${sort.state.checkSelected[option]?"selected":""}> ${option.label} </option> </c:forEach> </select> <!-- ... --> 15 Rendering example: Sort options
  • 16. <!-- ... --> <c:set var="controllers" value="${search.controller}"/> <!-- ... --> <c:set var="sort" value="${controllers.sorting}"/> <!-- ... --> <select name="${sort.config.sortParam}"> <c:forEach var="option" items="${sort.config.sortOptions}"> <option value="${option.paramValue}" ${sort.state.checkSelected[option]?"selected":""}> ${option.label} </option> </c:forEach> </select> <!-- ... --> 16 Rendering example: Sort options Use abbreviations
  • 17. <!-- ... --> <c:set var="controllers" value="${search.controller}"/> <!-- ... --> <c:set var="sort" value="${controllers.sorting}"/> <!-- ... --> <select name="${sort.config.sortParam}"> <c:forEach var="option" items="${sort.config.sortOptions}"> <option value="${option.paramValue}" ${sort.state.checkSelected[option]?"selected":""}> ${option.label} </option> </c:forEach> </select> <!-- ... --> 17 Rendering example: Sort options Use the configuration
  • 18. <!-- ... --> <c:set var="controllers" value="${search.controller}"/> <!-- ... --> <c:set var="sort" value="${controllers.sorting}"/> <!-- ... --> <select name="${sort.config.sortParam}"> <c:forEach var="option" items="${sort.config.sortOptions}"> <option value="${option.paramValue}" ${sort.state.checkSelected[option]?"selected":""}> ${option.label} </option> </c:forEach> </select> <!-- ... --> 18 Rendering example: Sort options Use the state
  • 19. <!-- ... --> <c:forEach var="searchResult" items="${search.searchResults}"> <a href='<cms:link>${searchResult.fields["path"]}</cms:link>'> ${searchResult.fields["Title_prop"]} </a> <p> ${cms:trimToSize( fn:escapeXml(searchResult.fields["content_en"]) ,250)} </p> <hr /> </c:forEach> <!-- ... --> 19 Rendering example: Results
  • 20. <!-- ... --> <c:forEach var="searchResult" items="${search.searchResults}"> <a href='<cms:link>${searchResult.fields["path"]}</cms:link>'> ${searchResult.fields["Title_prop"]} </a> <p> ${cms:trimToSize( fn:escapeXml(searchResult.fields["content_en"]) ,250)} </p> <hr /> </c:forEach> <!-- ... --> 20 Rendering example: Results Loop over the result collection (get I_CmsSearchResourceBean objects)
  • 21. <!-- ... --> <c:forEach var="searchResult" items="${search.searchResults}"> <a href='<cms:link>${searchResult.fields["path"]}</cms:link>'> ${searchResult.fields["Title_prop"]} </a> <p> ${cms:trimToSize( fn:escapeXml(searchResult.fields["content_en"]) ,250)} </p> <hr /> </c:forEach> <!-- ... --> 21 Rendering example: Results Access index fields
  • 22. <!-- ... --> <c:set var="fControllers" value="${controllers.fieldFacets}"/> <c:forEach var="facet" items="${search.fieldFacets}"> <c:set var="facetController" value="${fControllers.fieldFacetController[facet.name]}"/> <c:if test="${cms:getListSize(facet.values) > 0}"> <!-- Render facet – see next slide --> </c:if> </c:forEach> <!-- ... --> 22 Rendering example: Facets (I)
  • 23. <!-- ... --> <c:set var="fControllers" value="${controllers.fieldFacets}"/> <c:forEach var="facet" items="${search.fieldFacets}"> <c:set var="facetController" value="${fControllers.fieldFacetController[facet.name]}"/> <c:if test="${cms:getListSize(facet.values) > 0}"> <!-- Render facet – see next slide --> </c:if> </c:forEach> <!-- ... --> 23 Rendering example: Facets (I) Loop over facets from the search result
  • 24. <!-- ... --> <c:set var="fControllers" value="${controllers.fieldFacets}"/> <c:forEach var="facet" items="${search.fieldFacets}"> <c:set var="facetController" value="${fControllers.fieldFacetController[facet.name]}"/> <c:if test="${cms:getListSize(facet.values) > 0}"> <!-- Render facet – see next slide --> </c:if> </c:forEach> <!-- ... --> 24 Rendering example: Facets (I) Get the facet’s controller
  • 25. <!-- ... --> <c:set var="fControllers" value="${controllers.fieldFacets}"/> <c:forEach var="facet" items="${search.fieldFacets}"> <c:set var="facetController" value="${fControllers.fieldFacetController[facet.name]}"/> <c:if test="${cms:getListSize(facet.values) > 0}"> <!-- Render facet – see next slide --> </c:if> </c:forEach> <!-- ... --> 25 Rendering example: Facets (I) Render the facet if necessary (see next slide)
  • 26. <!-- ... --> <div>${facetController.config.label}</div> <c:forEach var="facetItem" items="${facet.values}"> <div class="checkbox"> <label> <input type="checkbox" name="${facetController.config.paramKey}" value="${facetItem.name}" ${facetController.state.isChecked[facetItem.name] ?"checked":""} /> ${facetItem.name} (${facetItem.count}) </label> </div> </c:forEach> <!-- ... --> 26 Rendering example: Facets (II)
  • 27. <!-- ... --> <div>${facetController.config.label}</div> <c:forEach var="facetItem" items="${facet.values}"> <div class="checkbox"> <label> <input type="checkbox" name="${facetController.config.paramKey}" value="${facetItem.name}" ${facetController.state.isChecked[facetItem.name] ?"checked":""} /> ${facetItem.name} (${facetItem.count}) </label> </div> </c:forEach> <!-- ... --> 27 Rendering example: Facets (II) Use the configuration
  • 28. <!-- ... --> <div>${facetController.config.label}</div> <c:forEach var="facetItem" items="${facet.values}"> <div class="checkbox"> <label> <input type="checkbox" name="${facetController.config.paramKey}" value="${facetItem.name}" ${facetController.state.isChecked[facetItem.name] ?"checked":""} /> ${facetItem.name} (${facetItem.count}) </label> </div> </c:forEach> <!-- ... --> 28 Rendering example: Facets (II) Use the result
  • 29. <!-- ... --> <div>${facetController.config.label}</div> <c:forEach var="facetItem" items="${facet.values}"> <div class="checkbox"> <label> <input type="checkbox" name="${facetController.config.paramKey}" value="${facetItem.name}" ${facetController.state.isChecked[facetItem.name] ?"checked":""} /> ${facetItem.name} (${facetItem.count}) </label> </div> </c:forEach> <!-- ... --> 29 Rendering example: Facets (II) Use the state
  • 30. <c:set var="pagination" value="${controllers.pagination}"/> <c:forEach var="i" begin="${search.pageNavFirst}" end="${search.pageNavLast}"> <c:set var="is">${i}</c:set> <li ${pagination.state.currentPage eq i ? "class='active'" : ""}> <a href="<cms:link>${cms.requestContext.uri} ?${search.stateParameters.setPage[is]} </cms:link>">${is}</a> </li> </c:forEach> <li> <c:set var="pages">${search.numPages}</c:set> <a href="<cms:link>${cms.requestContext.uri} ?${search.stateParameters.setPage[pages]} </cms:link>">Last</a> </li> 30 Rendering example: Pagination
  • 31. <c:set var="pagination" value="${controllers.pagination}"/> <c:forEach var="i" begin="${search.pageNavFirst}" end="${search.pageNavLast}"> <c:set var="is">${i}</c:set> <li ${pagination.state.currentPage eq i ? "class='active'" : ""}> <a href="<cms:link>${cms.requestContext.uri} ?${search.stateParameters.setPage[is]} </cms:link>">${is}</a> </li> </c:forEach> <li> <c:set var="pages">${search.numPages}</c:set> <a href="<cms:link>${cms.requestContext.uri} ?${search.stateParameters.setPage[pages]} </cms:link>">Last</a> </li> 31 Rendering example: Pagination Use pagination support
  • 32. <c:set var="pagination" value="${controllers.pagination}"/> <c:forEach var="i" begin="${search.pageNavFirst}" end="${search.pageNavLast}"> <c:set var="is">${i}</c:set> <li ${pagination.state.currentPage eq i ? "class='active'" : ""}> <a href="<cms:link>${cms.requestContext.uri} ?${search.stateParameters.setPage[is]} </cms:link>">${is}</a> </li> </c:forEach> <li> <c:set var="pages">${search.numPages}</c:set> <a href="<cms:link>${cms.requestContext.uri} ?${search.stateParameters.setPage[pages]} </cms:link>">Last</a> </li> 32 Rendering example: Pagination Use current state
  • 33. <c:set var="pagination" value="${controllers.pagination}"/> <c:forEach var="i" begin="${search.pageNavFirst}" end="${search.pageNavLast}"> <c:set var="is">${i}</c:set> <li ${pagination.state.currentPage eq i ? "class='active'" : ""}> <a href="<cms:link>${cms.requestContext.uri} ?${search.stateParameters.setPage[is]} </cms:link>">${is}</a> </li> </c:forEach> <li> <c:set var="pages">${search.numPages}</c:set> <a href="<cms:link>${cms.requestContext.uri} ?${search.stateParameters.setPage[pages]} </cms:link>">Last</a> </li> 33 Rendering example: Pagination Use state parameters
  • 34. ● Two options to send the current state: ● Submit a form ● Use state parameters ● With state parameters ● Everything is manipulated explicitly ● You do not need a form at all ● With a form ● You must make sure to send all the state you want (use hidden parameters, e.g., for the last query) ● You can intentionally prevent state transmission (e.g., for the current page) 34 Form vs. state parameters
  • 35. ● We did ● Introduce the tag <cms:search> ● See its configuration via an XML content ● Explore how to write a formatter for a search form ● If you need more information on formatting ● Explore the default formatter ● Explore the classes under org.opencms.jsp.search.result ● We did not ● Cover all configuration options ● See all use cases for <cms:search> 35 Short summary
  • 36. ● Intention ● Show blogs, news, ... ● Link to detail pages ● Realization ● <cms:contentload> ● Manifold collectors ● Question ● Where’s the difference between lists and a search result page? 36 Lists in OpenCms
  • 37. ● Intention ● Show blogs, news, ... ● Link to detail pages ● Realization ● <cms:contentload> ● Manifold collectors ● Question ● Where’s the difference between lists and a search result page? 37 Lists in OpenCms Essentially, there is no difference!
  • 38. 38 A short history of lists ● Simple way to render lists ● Many specific collectors ● Facility to edit list entries directly OpenCms 6.0 <cms:contentload> is introduced OpenCms 8.5 ● Collecting “byQuery” or “byContext” ● First contact of Search and Lists ● No facets etc. supported CmsSolrCollector is added OpenCms 10 <cms:search> and <cms:edit> are introduced ● Lists and search become one ● Facets etc. available for lists ● Editing becomes decoupled from lists ?
  • 39. ● What is specific for a list? ● XML content for configuration is unsuitable ● There is no query string provided by the user ● Usually there is no form ● XML contents, not the index is accessed ● How does <cms:search> handle the pecularities ● Configuration via JSON (String or file) ● An option to ignore the query parameter ● The already seen state parameters (no form is necessary) ● I_CmsSearchResourceBean allows to access XML contents via the CmsJspContentAccessBean 39 Lists with <cms:search>
  • 40. ● Live Demo Watch out for the Solr features Demo Demo Demo Demo デモ A list with <cms:search>
  • 41. <c:set var="searchConfig"> { "ignorequery" : true, "extrasolrparams" : "fq=type:u-blog&fq=parent-folders: "/sites/default/.content/blogentries/"", "pagesize" : ${content.value.pageSize}, "pagenavlength" : ${cms.element.settings["navlength"]} <!-- Facet and sort option configuration --> } </c:set> <cms:search configString="${searchConfig}" var="search"/> <!-- ... --> 41 The JSON configuration for a list
  • 42. <c:set var="searchConfig"> { "ignorequery" : true, "extrasolrparams" : "fq=type:u-blog&fq=parent-folders: "/sites/default/.content/blogentries/"", "pagesize" : ${content.value.pageSize}, "pagenavlength" : ${cms.element.settings["navlength"]} <!-- Facet and sort option configuration --> } </c:set> <cms:search configString="${searchConfig}" var="search"/> <!-- ... --> 42 The JSON configuration for a list Most important options
  • 43. <c:set var="searchConfig"> { "ignorequery" : true, "extrasolrparams" : "fq=type:u-blog&fq=parent-folders: "/sites/default/.content/blogentries/"", "pagesize" : ${content.value.pageSize}, "pagenavlength" : ${cms.element.settings["navlength"]} <!-- Facet and sort option configuration --> } </c:set> <cms:search configString="${searchConfig}" var="search"/> <!-- ... --> 43 The JSON configuration for a list Optional extra features
  • 44. <c:set var="searchConfig"> { "ignorequery" : true, "extrasolrparams" : "fq=type:u-blog&fq=parent-folders: "/sites/default/.content/blogentries/"", "pagesize" : ${content.value.pageSize}, "pagenavlength" : ${cms.element.settings["navlength"]} <!-- Facet and sort option configuration --> } </c:set> <cms:search configString="${searchConfig}" var="search"/> <!-- ... --> 44 The JSON configuration for a list The content adjusts the configuration
  • 45. <c:choose> <c:when test="${search.numFound > 0}"> <c:forEach var="result" items="${search.searchResults}"> <c:set var="content" value="${result.xmlContent}"/> <!-- render entry as usual --> </c:forEach> </c:when> <c:otherwise> No results found. </c:otherwise> </c:choose> 45 Rendering the list entries Easier than before Getting results and iterating over them is separated No nested <cms:contentload> anymore
  • 46. ● <cms:contentload> supported ● Editing, adding or deleting list entries ● Adding entries to an empty list ● Can we provide the same feature? ● No, because iteration is separated from <cms:search> ● Do we need the same feature? ● No, there’s no reason why edit options and content loading has to be coupled ● Can we get similar edit options differently? ● Yes, a special <cms:edit> tag 46 Editing list entries
  • 47. ● Places edit points wherever you like ● Allows to edit or delete existing XML contents ● Allows to add new contents ● Highlights the enclosed HTML when hovering over the edit point ● New contents can be placed ● At the place configured in the sitemap configuration ● In a provided folder ● Where the content that is edited is located 47 The tag <cms:edit>
  • 48. <c:choose> <c:when test="${search.numFound > 0}"> <c:forEach var="result" items="${search.searchResults}"> <c:set var="content" value="${result.xmlContent}"/> <cms:edit uuid='${result.fields["id"]}' create="true" delete="true"> <!-- render entry as usual --> </cms:edit> </c:forEach> </c:when> <c:otherwise> <cms:edit createType="u-blog"> <div>No results found.</div> </cms:edit> </c:otherwise> </c:choose> 48 Edit options for the list Easier than before Harmonized usage for empty and non-empty list
  • 49. ● How about the “Publish this page” option? ● <cms:contentload> with attribute “editable” causes list entries to be related to the page ● Do we have a similar mechanism? ● Using <cms:edit> the edited content becomes related to the page ● But does this suffice? ● Not if we use pagination. ● So can we do better? ● Yes: <cms:search ... addContentInfo="true"> ● All list entries become related to the page 49 Do we still miss a feature?
  • 50. 50 What should you remember? Server-sided Solr search becomes easy Search pages and lists become the same Edit point needed: Use <cms:edit> By, by <cms:contentload> and friends
  • 51. ● Containers in lists ● Container tag takes the element(s) <cms:container ... elements="${uuid}"/> ● Rendering is done by a suitable formatter 51 What’s next? (Maybe) Easily render contents of different types Inline editing will work out of the box Harmonized rendering of XML contents
  • 52. ● Containers in lists ● Container tag takes the element(s) <cms:container ... elements="${uuid}"/> ● Rendering is done by a suitable formatter 52 What’s next? (Maybe) Easily render contents of different types Inline editing will work out of the box Harmonized rendering of XML contents
  • 53. 53 Last comments Solr updated to version 5.1 (further updates follow) Gallery index replaced by “Solr offline” (watch out for bugs) This is OpenCms 10 Alpha 1 (don’t expect everything in the final state)
  • 54. Daniel Seidel Alkacon Software GmbH http://www.alkacon.com http://www.opencms.org Thank you very much for your attention!