# Widgets no CMS do Total.js: use-os numa página e escreva os seus

> Como aparece um widget no HTML de uma página (o atributo data-cms e o seu JSON), as partes de um ficheiro de widget, o marcador CLASS, renderizar um widget no servidor com exports.render e instalar widgets pela API.

Framework: cms
Product: CMS (cms@8071e48)
Language: pt
Content-SHA256: 3a90ba22c88e3ea672201d2db5ba9ad590d03ce47c7ab5b8729b9bffc90d7c7c
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: 
Review: not-recorded

Um **widget** é um bloco que coloca numa página: um título, um aviso, uma galeria. Leva o seu próprio estilo, um formulário para o configurar no editor e, opcionalmente, código que o renderiza no servidor. Um widget é um ficheiro HTML, como um componente do [Flow](/en/flow/write-a-component/), e o CMS guarda-o nos seus metadados.

## Um widget dentro de uma página

No HTML de uma página, um widget é um `div` com dois atributos:

```html
<div data-cms="headline__%7B%22h%22%3A%22h1%22%2C%22align%22%3A%22left%22%7D" data-cms-id="h1">
	<h1 class="w-headline-h">Hello CMS</h1>
	<p>Some text</p>
</div>
```

- `data-cms` é `<widget id>__<configuration>`, em que a configuração é um objeto JSON escrito com `encodeURIComponent`. O editor escreve-o; pode escrevê-lo você quando gera páginas.
- `data-cms-id` é o identificador da instância na página.

Quando a página é servida, o CMS remove o atributo `data-cms`, mantém o HTML que está dentro e acrescenta ao head o estilo de cada widget da página. Se o widget não estiver instalado, o seu bloco é descartado.

## As partes de um ficheiro de widget

| Parte | Para que serve |
|---|---|
| `<script total>` | os metadados e o código do servidor: `exports.id`, `name`, `author`, `version`, `preview` (uma imagem ou um data URI), `config` (os valores predefinidos) e, opcionalmente, `dependencies`, `install`, `uninstall` e `render` |
| `<style>` | o CSS do widget |
| `<body>` | o design do widget tal como o editor o mostra; os elementos com a classe `CMS_edit` são os editáveis; as outras classes `CMS_*` (`CMS_repeat`, `CMS_remove`, `CMS_unwrap`...) são marcadores para o editor, e o compilador remove-as antes de servir a página |
| `<settings>` | o formulário que edita `config` no editor (entradas do jComponent cujo caminho começa por `?.`) e um `<script>` com `exports.save(config, el)` que altera o design quando a configuração muda |
| `<template>` | um modelo opcional para o widget |
| `<readme>` | a ajuda do widget |

`CLASS` no estilo, nas definições, no modelo e no design é substituído por uma classe que pertence ao widget (`w-` seguido do seu id), de modo que dois widgets nunca partilham uma regra: no widget `alert`, `.CLASS-color1` passa a `.w-alert-color1`.

`exports.dependencies` aceita uma lista ou uma cadeia separada por vírgulas: um endereço que termina em `.js` torna-se um `<script src>` e um que termina em `.css` um `<link rel="stylesheet">`, acrescentados ao head da página.

## Renderizar no servidor

Um widget sem `exports.render` é apenas limpo e servido tal como está. Com `render` pode construir o seu HTML a partir da configuração:

```html
<script total>

	exports.id = 'hello';
	exports.name = 'Hello';
	exports.author = 'Me';
	exports.version = '1';
	exports.config = { text: 'world' };

	exports.render = function(opt, next) {
		next('<p class="w-hello">Hello ' + (opt.config.text || '').toUpperCase() + '</p>', true);
	};

</script>

<style>
	.CLASS { color: #07c; }
</style>

<body>
	<p class="CLASS CMS_edit">Hello world</p>
</body>
```

`opt.config` é a configuração da instância, `opt.html` o HTML que estava dentro do bloco, e `opt.id`, `opt.uid` e `opt.body` descrevem-no. `next(html, replace)` entrega o HTML a servir; com `true` como segundo argumento substitui o bloco todo. Guardámos este ficheiro num CMS local e uma página com `data-cms="hello__..."` e `{"text":"mundo"}` saiu como `<p class="w-hello">Hello MUNDO</p>`, com `.w-hello{color:#07c}` no head. O widget oficial `picture` usa a mesma função para acrescentar `loading="lazy"` à sua imagem, e `code` para imprimir o código das suas definições.

`exports.install` e `exports.uninstall` correm com a base de dados do CMS quando o widget é adicionado, alterado ou removido.

## Instalar e remover widgets

O plugin *Widgets* do admin importa um ficheiro; pela API é `widgets_save` com `{ "html": "<file content>", "singleton": true }` (`singleton` ignora o widget se já existir), `widgets_list`, `widgets_read`, `widgets_detail` e `widgets_remove`. Precisam da permissão `widgets` (veja [a API do admin](/en/cms/the-admin-api/)). Os 43 widgets oficiais estão em [o repositório de widgets](/en/cms/the-widgets-repository/).
