# Metadata

## Globally defined

For selecting metadata definitions defined on the site for usage in templates use the [DropdownSelector](/packages/config-svelte/components/dropdownselector/) component with `type="metadata"`.

```svelte
<script>
  import { Panel, DropdownSelector } from '@soleil-se/config-svelte';
</script>


<Panel heading="Inställningar">
  <DropdownSelector name="metadata" type="metadata" label="Metadata" />
</Panel>
```

> **Limit type selection**
>
> Remeber to limit the selection to the metadata types using the `selectable` prop, this lowers the risk of errors and makes the life of an editor easier. See Selectable types in the [DropdownSelector documentation](/packages/config-svelte/components/dropdownselector/#selectable-types).

## Locally defined

Somethimes you want to define metadata directly on a page, folder, archive, the file or image repositories. In the standard DropdownSelector for selecting metadata it’s only possible to select metadata defined on the site for usage in templates.

This example shows how to get metadata defined locally on a node.

You need to use [MetadataDefinitionUtil](https://developer.sitevision.se/webdav/files/apidocs/senselogic/sitevision/api/metadata/MetadataDefinitionUtil.html) in `config/index.js` to fetch the metadata definitions from a node to create the options array.\
In the the config app we use a [CustomSelector](/packages/config-svelte/components/customselector/) to be able to pass in our own options.

### Current page

If you want to get metadata definitions from the current page use `PortletContextUtil.getCurrentPage()` to get the current node.

**index.js**

```js
import router from '@sitevision/api/common/router';
import MetadataDefinitionUtil from '@sitevision/api/server/MetadataDefinitionUtil';
import Properties from '@sitevision/api/server/Properties';
import PortletContextUtil from '@sitevision/api/server/PortletContextUtil';


import { createAppProps } from '@soleil-se/config-svelte/server';


function getMetadataOptions(node) {
  if (!node) return [];
  return MetadataDefinitionUtil.getDefinitions(node)
    .toArray()
    .filter((definition) => !!definition.getName())
    .map((definition) => ({
      value: definition.getIdentifier(),
      label: `${Properties.get(definition, 'displayName')} (${definition.getName()})`,
    }));
}


router.get('/', (req, res) => {
  const currentPage = PortletContextUtil.getCurrentPage();
  const props = {
    options: getMetadataOptions(currentPage),
  };
  res.send(createAppProps(props));
});
```

**App.svelte**

```svelte
<script>
  import { Panel, CustomSelector, NodeSelector } from '@soleil-se/config-svelte';


  let { options } = $props();
</script>


<Panel>
  <CustomSelector name="metadata" label="Metadata" {options} />
</Panel>
```

### From global settings

If you want to get metadata definitions from a node defined in the global settings.

**index.js**

```js
import router from '@sitevision/api/common/router';
import MetadataDefinitionUtil from '@sitevision/api/server/MetadataDefinitionUtil';
import Properties from '@sitevision/api/server/Properties';
import globalAppData from '@sitevision/api/server/globalAppData';


import { createAppProps } from '@soleil-se/config-svelte/server';


function getMetadataOptions(node) {
  if (!node) return [];
  return MetadataDefinitionUtil.getDefinitions(node)
    .toArray()
    .filter((definition) => !!definition.getName())
    .map((definition) => ({
      value: definition.getIdentifier(),
      label: `${Properties.get(definition, 'displayName')} (${definition.getName()})`,
    }));
}


router.get('/', (req, res) => {
  const globalAppDataNode = globalAppData.getNode('node');
  const props = {
    options: getMetadataOptions(globalAppDataNode),
  };
  res.send(createAppProps(props));
});
```

**App.svelte**

```svelte
<script>
  import { Panel, CustomSelector, NodeSelector } from '@soleil-se/config-svelte';


  let { options } = $props();
</script>


<Panel>
  <CustomSelector name="metadata" label="Metadata" {options} />
</Panel>
```

### From the same config

If you want to get metadata definitions from a node selected in the current config you need to dynamically fetch these.\
This requires an additional route to get the metadata definitions based on the selected node, for this request we use [@soleil-se/config-requester](https://docs.soleil.se/packages/config-requester/)

**index.js**

```js
import router from '@sitevision/api/common/router';
import MetadataDefinitionUtil from '@sitevision/api/server/MetadataDefinitionUtil';
import ResourceLocatorUtil from '@sitevision/api/server/ResourceLocatorUtil';


function getMetadataOptions(node) {
  if (!node) return [];
  return MetadataDefinitionUtil.getDefinitions(node)
    .toArray()
    .filter((definition) => !!definition.getName())
    .map((definition) => ({
      value: definition.getIdentifier(),
      label: `${Properties.get(definition, 'displayName')} (${definition.getName()})`,
    }));
}


router.get('/', (req, res) => {
  res.send('');
});


router.get('/metadata', (req, res) => {
  const node = ResourceLocatorUtil.getNodeByIdentifier(req.params.id);
  if (!node) res.json([]);
  res.json(getMetadataOptions(node));
});
```

**App.svelte**

```svelte
<script>
  import { Panel, CustomSelector, NodeSelector } from '@soleil-se/config-svelte';
  import requester from '@soleil-se/config-requester';


  let options = $state([]);


  async function onChange(event) {
    const id = event.detail;
    if (!id) {
      options = [];
      return;
    }
    options = await requester('/metadata', { data: { id } });
  }
</script>


<Panel>
  <NodeSelector name="node" label="Nod" on:change={onChange} />
  <CustomSelector name="metadata" label="Metadata" disabled={options.length === 0} {options} />
</Panel>
```

### Get selected metadata definition

To get the a metadata definition from config you use [appData](https://developer.sitevision.se/docs/webapps/sdk/appdata) or [globalAppData](https://developer.sitevision.se/docs/webapps/sdk/globalappdata)

```js
import appData from '@sitevision/api/server/appData';
const metadataDefinition = appData.getNode('metadata');
```

To get the `name` or “identifier” from a metadata to use when getting properties from a node.

```js
import appData from '@sitevision/api/server/appData';
import Properties from '@sitevision/api/server/Properties';


const metadata = appData.get('metadata', 'name');
const metadataValue = Properties.get(node, name);
```

### Get selected metadata values

To get want the values of a `sv:metadataSingleDefinition` or `sv:metadataMultipleDefinition`.

```js
import appData from '@sitevision/api/server/appData';
import Properties from '@sitevision/api/server/Properties';


function getMetadataValues(definition) {
  if (!definition) return [];
  return Properties
    .getArray(definition.getNodes())
    .map((id) => Properties.get(id, 'displayName'));
}


const metadataDefinition = appData.getNode('metadata');
const metadataValues = getMetadataValues(metadataDefinition);
```