Skip to content

Commit

Permalink
Merge branch 'release/4.7.0-beta' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
FranckyC committed Jul 1, 2022
2 parents d3d8bba + 6bb8cbf commit af71d24
Show file tree
Hide file tree
Showing 120 changed files with 4,703 additions and 18,102 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
125 changes: 105 additions & 20 deletions docs/extensibility/templating.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
# Customize layout templates with HTML, CSS and Handlebars
# Customize layout templates

In a basic customization scenario, super users and webmasters can customize existing templates or start from a blank template to adapt the UI to their requirements. Templates use [Handlebars](https://handlebarsjs.com/) to display data retrieved from the data source. There are several options to customize a template:
In a basic customization scenario, super users and webmasters can customize existing templates or start from a blank template to adapt the UI to their requirements. Templates can use either [Handlebars](https://handlebarsjs.com/) or [Adaptive cards](https://adaptivecards.io/) templates to display data retrieved from the data source. Depdending of the template type, there are several options to customize a template:

- Use regular HTML markup, Handlebars syntax and [helpers](#handlebars-helpers).
- [Use default web components provided by the solution](#using-builtin-web-components).
- [Write custom CSS styles](#custom-css-styles).
- [Use Microsoft Graph Toolkit components](#microsoft-graph-toolkit).
- **Handlebars**
- Use regular HTML markup, Handlebars syntax and [helpers](#handlebars-helpers).
- [Write custom CSS styles](#custom-css-styles).
- **Adaptive cards**
- Use declarative [Adaptive Cards](#adaptive-cards-customizations) JSON templates with data.
- **Both techniques**
- Use data sources [slots](../usage/data-visualizer/slots.md)
- Use default [web components](#using-builtin-web-components) provided by the solution.
- Use [Microsoft Graph Toolkit components](#microsoft-graph-toolkit).

> The templates and fields HTML markup is sanitized automatically preventing XSS attacks. We used [`DOMPurify`](https://github.com/cure53/DOMPurify) to do so. It means for instance, you cannot add your own `<script>` tags or inline JavaScript.
## Handlebars, HTML and CSS customizations

!["Handlebars"](../assets/extensibility/handlebars_templating.png){: .center}

## Template structure
> The templates and fields HTML markup is sanitized automatically preventing XSS attacks. We used [`DOMPurify`](https://github.com/cure53/DOMPurify) to do so. It means for instance, you cannot add your own `<script>` tags or inline JavaScript.
### Template structure

A layout template is always split into two distinct parts:

Expand All @@ -28,7 +36,7 @@ A layout template is always split into two distinct parts:

Both can use Handlebars and web components (Microsoft Graph Toolkit included).

## Handlebars helpers
### Handlebars helpers

The following custom helpers are available in addition to the [handlebars-helpers](https://github.com/helpers/handlebars-helpers). If those don't do the job for you, you can still write your own using the [extensibility library](./handlebars_customizations.md).

Expand All @@ -37,10 +45,10 @@ The following custom helpers are available in addition to the [handlebars-helper
| Helper | Description | Example |
| ------ | ----------- | -------- |
| `{{getGraphPreviewUrl "<absolute_URL>"` | Try to determine the preview URL based on an absolute URL using the unified Microsoft Graph URL syntax. For instance, _https://contoso.sharepoint.com/sites/dev/Shared%20Documents/MyDocument.pdf_ becomes _https://contoso.sharepoint.com/sites/dev/Shared%20Documents/?id=/sites/dev/Shared%20Documents/MyDocument.pdf&parent=/sites/dev/Shared%20Documents_ | `{{getGraphPreviewUrl 'https://contoso.sharepoint.com/sites/dev/Shared%20Documents/MyDocument.pdf'}}`
`{{getCountMessage <total items count> <?keywords>}}` | Display a friendly message displaying the result and the entered keywords. | `{{getCountMessage 5 'contoso'}}` will display _'5 results for 'contoso'_.
`{{getCountMessage <total items count> <keywords>}}` | Display a friendly message displaying the result and the entered keywords. | `{{getCountMessage 5 'contoso'}}` will display _'5 results for 'contoso'_.
| `{{getSummary "<value>"}}` | _Use with SharePoint Search data source and the HitHighlightedSummary SharePoint search managed property_. Returns the formatted value for rendering. | `{{getSummary HitHighlightedSummary}}`
| `{{getTagName "<value>"}}` | _Use with tag fields_. Returns the name of the tag, omitting the ID in the tag string (`L0\|#000000000-0000-0000-0000-000000000000\|…`). | `{{getTagName Tag}}`
| `{{getDate <data_value> "<format>" <time handling>}}` | Format the date with [Moment.js](https://momentjs.com/docs/#/parsing/string-format/) according to the current language. Date in the managed property should be on the form `2018-09-10T06:29:25.0000000Z` for the function to work.<p>&lt;time handling&gt; is optional and takes <ul><li>0 = format to browsers time zone (default)</li><li>1 = ignore Z time and handle as browsers local time zone</li><li>2 = strip time and set to 00:00:00 in browsers local time zone</li><li>3 = display in the time zone for the current web</li><li>4 = display in the time zone from the uers profile</li> | `{{getDate 2018-09-10T06:29:25.0000000Z 'LL'}}`
| `{{getDate <data_value> "<format>" "<time handling>"}}` | Format the date with [Moment.js](https://momentjs.com/docs/#/parsing/string-format/) according to the current language. Date in the managed property should be on the form `2018-09-10T06:29:25.0000000Z` for the function to work.<p>&lt;time handling&gt; is optional and takes <ul><li>0 = format to browsers time zone (default)</li><li>1 = ignore Z time and handle as browsers local time zone</li><li>2 = strip time and set to 00:00:00 in browsers local time zone</li><li>3 = display in the time zone for the current web</li><li>4 = display in the time zone from the uers profile</li> | `{{getDate 2018-09-10T06:29:25.0000000Z 'LL'}}`
| `{{getUrlField <managed_propertyOWSURLH> "URL|Title"}}` | _Use with SharePoint Search data source_. Returns the URL or Title part of a URL autocreated managed property | `{{getUrlField MyPropertyOWSURLH "Title"}}`
`{{getUniqueCount items "<property>"}}` or `{{getUniqueCount array}}`| Get the unique count of a property over the result set (or another array) or get the unique count of objects in an array. Example: [1,1,1,2,2,4] would return `3`. | `{{getUniqueCount [1,1,1,2,2,4]}}`
`{{getUnique items "<property>"}}` | Return the unique values as a new array based on an array or property of an object in the array. | `{{getUnique items "NewsCategory"}}`
Expand All @@ -52,15 +60,17 @@ The following custom helpers are available in addition to the [handlebars-helper
| `{{getPageContext "<SPFx page property>"}}` | Retrieve a property from the SPFx context object. | `{{getPageContext "user.displayName"}}` or `{{getPageContext "cultureInfo.currentUICultureName"}}`
| `{{getAttachments}}`| Return object structure for list item attachments. | `{{#getAttachments LinkOfficeChild}}<a href="{{url}}">{{index}} - {{fileName}}</href>{{/getAttachments}}`
| `{{dayDiff <date1> <date2>}}`| Return the number of days between two dates, eg. show an icon for files created within the last 30 days. | `{{#compare (dayDiff (getDate Created 'YYYY-MMM-DD' ) (getDate timestamp 'YYYY-MMM-DD' )) "<=" 30 }} <img src='/SiteAssets/New.png' />{{/compare}}`
| `{{urlParse <url>}}` | Same as Handlebar Helpers. Omitting the optional url parameter uses the current browser URL. | `{{get "query" (urlParse)}}` return the query part of a URL
| `{{getUrlParameter <parameter> <url>}}` | Return the query parameter value from a URL. Omitting the optional url parameter uses the current browser URL. | `{{getUrlParameter "k"}}` return the value of the `k` query parameter from the browser URL.<br><br>`{{getUrlParameter "k" "https://foo?k=test"}}` return the value of the `k` query parameter from the provided URL.


> Need any other helper? Let us know [here](https://github.com/aequos-solutions/modern-search-results/issues)!
## Using builtin web components
### Using builtin web components

By default, several components are available ([see the complete list](./web_components_list.md)). If these does not fit your requirement, you can still create your own using the [extensibility library](./custom_web_component.md).

## Custom CSS styles
### Custom CSS styles

Inside an HTML template (or layout field), you can write your own CSS styles using a &lt;style&gt; tag. Even better, you can inject Handlebars variables, helpers, conditional blocks, etc. right inside it and get dynamic classes or attributes

Expand All @@ -80,7 +90,7 @@ Inside an HTML template (or layout field), you can write your own CSS styles usi
However, all CSS rules (including `@media` rules) will be all prefixed automatically by an unique ID (**pnp-template_&lt;Web Part instance ID&gt;**) to make sure styles are isolated from other Web Parts on the page. We do this to avoid conflicts between classes in the global context.
## Hide error message using CSS
### Hide error message using CSS
By default the web parts will output an error message if something goes wrong on for example API calls.
If you want to hide the error message you can add the following CSS in your custom template.
Expand All @@ -98,7 +108,7 @@ If you want to hide the error message you can add the following CSS in your cust
...
```
## Use SharePoint theme in your templates
### Use SharePoint theme in your templates
If you need to use current site theme colors, fonts and so on you can use the `theme` property available in the `@root` Handlebars context like this:
Expand Down Expand Up @@ -129,12 +139,12 @@ A good way to see all available values for the current theme is to switch to the
![Theme properties](../assets/theme_debug.png)
## Work with placeholders
### Work with placeholders
To indicate the data are loading, you can create placeholders (shimmers) using the `<content id="placeholder-content">` section of your HTML template:
The placeholder is only loaded during first data load. For subsequent requests, a overlay will be displayed.
```
```html
<content id="placeholder-content">
<style>
Expand Down Expand Up @@ -174,15 +184,15 @@ Use CSS classes `placeholder--shimmer` and `placeholder--line` to build your pla

If no placeholder is present in the template, a default one will be loaded.

## Microsoft Graph Toolkit
### Microsoft Graph Toolkit

> The Microsoft Graph Toolkit is a collection of reusable, framework-agnostic web components and helpers for accessing and working with Microsoft Graph. The components are fully functional right of out of the box, with built in providers that authenticate with and fetch data from Microsoft Graph.
In the solution, you can use Graph Tookit components whitout the need to re-authenticate against Microsoft Graph because the Web Parts already use the [SharePoint provider](https://docs.microsoft.com/en-us/graph/toolkit/providers/sharepoint).

Refer to the official documentation to see [all available components](https://docs.microsoft.com/en-us/graph/toolkit/components/login). For instance, we use the Microsoft Graph Toolkit for the [people layout](../usage/search-results/layouts/people.md) via `<mgt-person>`.

## Build templates with item selection
### Build templates with item selection

If your template requires items selection for dynamic filtering, you can follow these guidelines to design your template structure. The item selection feature is based on the Office Fluent UI [**Selection**](https://developer.microsoft.com/en-us/fluentui#/controls/web/selection) component and custom `data` attributes.

Expand All @@ -206,7 +216,7 @@ As item key you must use the builtin Handlebars `{{@index}}` property in the `{{

**Template example with item selection**

```
```html
<style>
.selected {
Expand All @@ -227,3 +237,78 @@ As item key you must use the builtin Handlebars `{{@index}}` property in the `{{
!!! note
- If you allowed multi items selection, you must use `CTRL` + `Left click` to select multiple elements. You can also select a range of elements using `SHIFT` + `Left click`.
## Adaptive cards customizations
!["Adaptive Cards"](../assets/extensibility/adaptive_cards_templating.png){: .center}
As defined by Microsoft:
_"Adaptive Cards are platform-agnostic snippets of UI, authored in JSON, that apps and services can openly exchange. When delivered to a specific app, the JSON is transformed into native UI that automatically adapts to its surroundings. It helps design and integrate light-weight UI for all major platforms and frameworks."_
This new way of displaying data can be used in the Modern Data Visualizer solution as well.
> You can use the adaptive cards builder to create your template [https://www.adaptivecards.io/designer/](https://www.adaptivecards.io/designer/).
> Adaptive cards can be used for SharePoint Search and Micrososft Search data sources.
### Use web components and HTML markup in adaptive cards
Web components and HTML are supported in adaptive cards through markdown processing. To use it simply, add your HTML markup in the text property. Example:
```json
...
{
"type": "Column",
"items": [
{
"type": "TextBlock",
"wrap": true,
"text": "<aequos-iconfile class='icon' data-extension='${string(jPath($data, concat('.',$root.slots['FileType']))[0])}'></aequos-iconfile>"
}
],
"width": "auto"
}
...
```
> HTML in adaptive cards will be sanitized.
### Reference a slot in a adaptive card
Since it is not possible to create custom functions with adaptive cards templates right now, slots values can only be accessed using the builtin [`jPath` function](https://docs.microsoft.com/en-us/azure/bot-service/adaptive-expressions/adaptive-expressions-prebuilt-functions?view=azure-bot-service-4.0#jPath) and the following syntax:
```json
"items": [
{
"type": "TextBlock",
"wrap": true,
"text": "${string(jPath($data, concat('.',$root.slots['<your_slot_name>']))[0])}""
}
],
```
To reference a field without a slot, just use its name:
```json
"items": [
{
"type": "TextBlock",
"wrap": true,
"text": "${Title}""
}
],
```
**Explanation**
- `string()` is here to make sure the result of the jPath expression will always be a string. **If omitted, if the slot provided (i.e. the object path) doesn't exist, it will return `null` causing a render error**. The `jPath` function always returns an array.
- `jPath(<data>, concat('.', $root.slots['<your_slot_name>']))` where `<data>` is the JSON object used to resolve the slot. When looping through `items`, use the `$data` token representing the current item with properties. The expression `concat('.', $root.slots['<your_slot_name>']))` is to comply with the jPath syntax: every property path should be begin with a '.' (See the official jPath [documentation](https://www.npmjs.com/package/jspath)).
### Styling your adaptive cards
When selecting the adaptive cards mode, you can also setup styles through the [host configuration](https://docs.microsoft.com/en-us/adaptive-cards/rendering-cards/host-config).
From the official Microsoft documentation:
_"HostConfig is a cross-platform configuration object that specifies how an Adaptive Card Renderer generates UI."_.
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,3 @@ Both pages are configured, the query will be transfered from one page to the oth

## Test your configuration
The query from the Search Box is sent to the Search Results. When you switch to an other Search Page, that are configured in the Vertical, the new page is open in the same tab an the query input will be transferred to the Search Results and Verticals on the second page.

https://user-images.githubusercontent.com/65955023/153156591-b478154d-23a3-40b4-aad9-6102dd4d41e7.mp4
60 changes: 60 additions & 0 deletions docs/scenarios/Create-a-useful-People-Search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Create a useful People Search

!!! note
The PnP Modern Search Web Parts must be deployed to your App Catalog and activated on your site. See the [installation documentation](../installation.md) for details.

This scenario describes how to configure a People Search with the PnP Modern Search Web Parts. You can search people in the Search Box or use filters with the Filters Web Part. With the defined layouts you can show your People Results with relevant information about the person. It's a basic configuration for a useful People Search, the PnP Web Parts have a lot more settings to configure.

## Create a new SharePoint page
To add the Search Web Parts, you must first create a new modern SharePoint page. We will be configure this new page as a search page with the PnP Modern Search Web Parts.

![Create a page](assets/create-a-useful-people-search/Create-a-page.png)

## Add PnP Search Web Parts
On the newly created page, add the PnP Modern Search Web Part Search Box, Search Filters and Search Results.

![Add PnP Web Parts](assets/create-a-useful-people-search/Add-PnP-Web-Parts.png)

The WebParts can be arranged and configured on the page as desired.

![arrange your serach web parts](assets/create-a-useful-people-search/arrange-your-search-web-parts.png)

## Configure Search Box
You can change the placeholder text to display in the Search Box, you can leave the default configuration for the other settings.

![configure Search Box](assets/create-a-useful-people-search/configure-Search-Box.png)

## Configure Search Filters
Connect your Search Filters Web Part to the existing Results Web Part under "Use data from these Web Parts" and customize filters with your own properties.

![configure Search Filters](assets/create-a-useful-people-search/configure-search-filters.png)

### Customize filters
Add your own filter properties to the Search Filters. This are the properties from the UPS (= SharePoint User Profile Service), check the propertiy settings in your SharePoint Search Schema.

![configure customize filters](assets/create-a-useful-people-search/configure-customize-filters.png)

## Configure Search Results
Use the SharePoint Search as source and configure the Search Results Web Part to show only people. Choose the existing default result source LocalPeopleResults. With the query template you can exclude admin oder system accounts. In this example, only show user with an email addess this contains mehr365.

![configure search results](assets/create-a-useful-people-search/configure-search-results.png)

### Layout configuration
It is a predefined people layout available for the people search. Use People as Search Results layout.

![search results layouts](assets/create-a-useful-people-search/search-results-layouts.png)

## Layout options
In the section layout options you can manage the people fields, that will be showing in the results. When you like an people hover card, then activate this option, but you need to activate API access for Microsoft Graph in your SharePoint admin center. Use also an component size for your results.

![search results layout options](assets/create-a-useful-people-search/search-results-layout-options.png)

### Web Part Connections
As the last step, activate the connections. Use the query from your configured Search Box, you can also configure a default value. Conntect your Search Results also to the Filters Web Part.

![search results connections](assets/create-a-useful-people-search/search-results-connections.png)

## Solution
After the configuration i have a useful People Search incl. Hover card, with basic configuration. You have a lot more filter and layout options that you can configure.

![people search](assets/create-a-useful-people-search/people-search.png)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit af71d24

Please sign in to comment.