> For the complete documentation index, see [llms.txt](https://mapasculturais.gitbook.io/documentacao-para-desenvolvedores/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mapasculturais.gitbook.io/documentacao-para-desenvolvedores/formacao-para-desenvolvedores/backend-dos-temas.md).

# Backend dos Temas

{% embed url="<https://www.youtube.com/watch?v=awh2ThRgv20>" %}

## Layouts, Visões e Template parts

Quando o controlador chama a renderização de uma visão, o HTML resultante é enviado para o arquivo de layout.

### Layouts

Os layouts são arquivos de template PHP e implementam a *moldura* das páginas. São os arquivos `.php` que ficam diretamente na pasta `layouts`. Normalmente, implementam (ou incluem) pelo menos um *header* e um *footer* e recebem numa variável `$TEMPLATE_CONTENT` o HTML da visão já renderizado.

* `layouts/default.php`: É o layout padrão utilizado pelo tema quando não é informado outro no controller ou template.&#x20;

A implementação do *BaseV1* é a seguinte:

```php
<?php
$this->part('header', $render_data);
echo $TEMPLATE_CONTENT;
$this->part('footer', $render_data);
```

* `layouts/panel.php`: É o layout utilizado pelas páginas do painel.&#x20;

A implementação do *BaseV1* é a seguinte:

```php
<?php
$this->part('header', $render_data);
$this->part('panel-nav', $render_data);
echo $TEMPLATE_CONTENT;
$this->part('panel-settings-nav', $render_data);

$this->part('footer', $render_data);
```

### Visões

As visões são arquivos de template PHP relacionados aos controladores e ficam na pasta `views/{controller_slug}`. Cada controlador tem seu conjunto de arquivos de visão. São renderizados pelo controlador quando invocado o método `Controller::render` e podem receber variáveis vindas do controlador.

O exemplo abaixo renderiza o arquivo `views/controlador/visao.php`, que recebe uma variável `$variavel` com valor `"valor"`:

```php
class Controlador extends \MapasCulturais\Controler {
   function GET_acao() {
      $this->render('exemplo', ['variavel' => 'valor']);
   }
}
```

### Template parts

Os template parts, como o nome diz, são partes de template que podem ser incluídas pelos arquivos de *layout*, de *visão* ou mesmo por outros *template parts*. Ficam na pasta `layouts/parts` e são compartilhados por todas as visões e controladores. São renderizados pela visão quando invocado o método `Theme::part` e podem receber variáveis.

No exemplo abaixo, uma visão inclui o template `layouts/parts/parte.php`, que recebe a variável `$titulo`.

```php
$this->part('parte', ['titulo' => 'Título']);
```

## Funções de template

Há algumas funções auxiliares para a utilização nos arquivos de layout, visão e template parts.

* [printDocumentMeta;](/documentacao-para-desenvolvedores/formacao-para-desenvolvedores/backend-dos-temas.md#printdocumentmeta)
* [getTitle](/documentacao-para-desenvolvedores/formacao-para-desenvolvedores/backend-dos-temas.md#gettitle);
* [bodyProperties](/documentacao-para-desenvolvedores/formacao-para-desenvolvedores/backend-dos-temas.md#bodyproperties);
* [head](/documentacao-para-desenvolvedores/formacao-para-desenvolvedores/backend-dos-temas.md#head);
* [bodyBegin](/documentacao-para-desenvolvedores/formacao-para-desenvolvedores/backend-dos-temas.md#bodybegin);
* [bodyEnd](/documentacao-para-desenvolvedores/formacao-para-desenvolvedores/backend-dos-temas.md#bodyend);
* [isEditable](/documentacao-para-desenvolvedores/formacao-para-desenvolvedores/backend-dos-temas.md#iseditable);
* [printScripts](/documentacao-para-desenvolvedores/formacao-para-desenvolvedores/backend-dos-temas.md#printscripts);
* [printStyles](/documentacao-para-desenvolvedores/formacao-para-desenvolvedores/backend-dos-temas.md#printstyles).

### `printDocumentMeta`

Imprime as tags `<meta >` configuradas na propriedade `$documentMeta` do tema, como no exemplo a seguir:

```php
   // $this é a instância do tema ativo
   $this->documentMeta[] = [
      'name' => 'viewport', 
      'content' => 'width=device-width, initial-scale=1, maximum-scale=1.0'
   ];
   $this->documentMeta[] = [
      "property" => 'og:title', 
      'content' => 'Mapa da Cultura'
   ];
   $this->documentMeta[] = [
      "property" => 'og:description', 
      'content' => 'Plataforma livre, gratuita e colaborativa de mapeamento'
   ];

   $this->printDocumentMeta();
```

O trecho acima resultará no HTML abaixo:

```markup
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0">
<meta property="og:title" content="Mapa da Cultura">
<meta property="og:description" content="Plataforma livre, gratuita e colaborativa de mapeamento">
```

### `getTitle`

Gera um título para a rota atual, de acordo com a seguinte regra:

1. Se for uma rota de entidade (single ou edição de agentes, espaços, projeto etc), o título retornado será **"{$entity->name} - {siteName}"**, por exemplo **"Fulano de Tal - Mapa da Cultura"**;
2. Se a rota for a home do mapas (controller `site`, action `index`), o título retornado será **"{siteName}"**, por exemplo **"Mapa da Cultura"**;
3. Se a rota dor a home do painel, o título retornado será **"Painel"**;
4. Nome configurado na aplicação em [$app->config\['routes'\]\['readbleNames'\]](https://github.com/mapasculturais/mapasculturais/blob/master/src/protected/application/conf/conf-base.d/routes.php).

### `bodyProperties`

Imprime as propriedades da tag `<body >`, baseado no que foi configurado nas propriedades `$bodyProperties` e `$bodyClasses`, como no exemplo a seguir:

```php
   // $this é a instância do tema ativo
   $this->bodyProperties['ng-app'] = "entity.app";
   $this->bodyProperties['ng-controller'] = "EntityController";

   $this->bodyClasses[] = 'agent';
   $this->bodyClasses[] = 'single';
   ?>
   <body <?php $this->bodyProperties() ?> >
```

O trecho acima resultará no HTML abaixo:

```markup
<body ng-app="entity.app" ng-controller="EntityController" class="agent single">
```

### `head`

Aplica o hook `mapasculturais.head` e invoca o método [printDocumentMeta](/documentacao-para-desenvolvedores/formacao-para-desenvolvedores/backend-dos-temas.md#printdocumentmeta). Deve ser utilizado no final da tag `<head>`.

```php
   <?php $this->head() ?>
</head>
```

### `bodyBegin`

Esta função deve ser invocada logo após a abertura da tag `<body>` e a única coisa que faz é aplicar o hook `mapasculturais.body:before`.

```php
<body <?php $this->bodyProperties() ?> >
    <?php $this->bodyBegin() ?>
```

### `bodyEnd`

Esta função deve ser invocada antes do fechamento da tag `<body>` e a única coisa que faz é aplicar o hook `mapasculturais.body:after`.

```php
    <?php $this->bodyAfter() ?>
</body>
```

### `isEditable`

Esta função indica se a aplicação está em uma página onde os campos devem ser editáveis (create ou edit).

```php
<?php if ($this->isEditable()): ?>
   <button>save</button>
<?php endif; >
```

### `printScripts`

Imprime a(s) tag(s) `<script >` dos scripts enfileirados do grupo informado.

```php
$this->enqueueScript('meu-grupo', 'meu-script', 'js/meu-script.js');

$this->printScritps('meu-grupo');
```

O trecho acima resultará no HTML abaixo:

```markup
<script type="text/javascript" src="http://localhost/assets/js/meu-script-1629894851.js"></script>
```

### `printStyles`

Imprime a(s) tag(s) `<link rel="stylesheet" >` dos scripts enfileirados do grupo informado.

```php
$this->enqueueStyle('meu-grupo', 'meu-estilo', "css/meu-estilo.css");

$this->printStyles('meu-grupo');
```

O trecho acima resultará no HTML abaixo:

```markup
<link href="http://localhost/assets/css/meu-estilo-1629894851.css" media="all" rel="stylesheet" type="text/css">
```

## Modais de Criação de Entidade (BaseV1)

As modais de criação de entidade implementadas na versão v5.0.0 do Mapas Culturais são renderizados utilizando a função `BaseV1\Theme::renderModalFor`, que renderiza o botão que abre a modal.

```php
<div class="btn btn-default add"> 
   <?php $this->renderModalFor('agent', false, 'Novo agente'); ?> 
</div>
```

## Resolução de Nome de Arquivo

Os arquivos de layout, visão, template parts e assets podem estar nas pastas do tema pai (BaseV1), do tema filho implementado, de um módulo ou de um plugin. Os temas, plugins e módulos incluem/registram seu caminho no tema ativo chamando a função `addPath` que cria um pilha de caminhos, dessa maneira quando um tema precisa utilizar um arquivo ele chama a função `resolveFilename` que passa pela pilha de caminhos procurando o arquivo. É importante observar que é uma pilha e não uma fila, ou seja o último caminho que foi incluído será o primeiro a ser pesquisado.

* `addPath`: Adiciona um caminho à pilha de caminhos de resolução de nome de arquivos;
* `resolveFilename`: Busca o arquivo na pilha de caminhos.

Por exemplo, vamos supor que o tema precisa incluir o arquivo `layouts/parts/teste.php`. Ele será procurado primeiro nos plugins ativos, depois nos módulos, depois no tema filho e, por último, no tema pai.

## Assets

### Enfileiramento de Scripts e Estilos

Para incluir os estilos e scripts necessários para a visão, deve-se utilizar os métodos `Theme::enqueueScript` e `Theme::enqueueStyle`. Deve-se, também, informar as dependências do script/estilo. Assim, o asset manager saberá ordenar os mesmos.&#x20;

Ainda, deve-se informar o grupo ao qual pertence o script/estilo, sendo que o BaseV1 utiliza o grupo `app` para os scripts e estilos desenvolvidos para a aplicação, e o grupo `vendor` para as bibliotecas incluídas.

### AssetManager

O [AssetManager](https://github.com/mapasculturais/mapasculturais/blob/master/src/protected/application/lib/MapasCulturais/AssetManager.php) gerencia a publicação de assets dos temas, plugins ou módulos, se encarregando de minificar os JS e CSS. Quando configurado deste jeito, ou para modo de desenvolvimento, ele faz uma cópia do arquivo para a pasta `/assets`, sem processá-lo.&#x20;

Quando configurado para fazer merge dos scripts/estilos, será criado um arquivo para cada grupo de enfileiramento, contendo o código de todos os estilos/scripts enfileirados.

### Funções includeAssets (BaseV1)

As funções ***includeAssets*** são funções que enfileiram e/ou publicam conjuntos de assets de determinadas funcionalidades ou contextos. Costumam ser chamadas via hook ou pelos arquivos de visão e partes de template:

* `includeVendorAssets`: Inclui os assets das bibliotecas utilizadas pelo frontend;
* `includeCommonAssets`: Inclui os assets utilizados por todas as páginas;
* `includeIbgeJS`: Enfileira JavaScript utilizado nos selects de estados/cidades brasileiras;
* `includeChatAssets`: Inclui os assets dos chat threads;
* `includeEditableEntityAssets`: Inclui os assets das páginas de edição das entidades;
* `includeSearchAssets`: Inclui os assets da página de busca;
* `includeMapAssets`: Inclui os assets necessários para;
* `includeAngularEntityAssets`: Inclui os assets necessários para os componentes/módulos angular.

## jsObject

A propriedade `$jsObject`, do tipo [ArrayObject](https://www.php.net/manual/pt_BR/class.arrayobject.php), é a maneira que o tema do Mapas Culturais oferece para o desenvolvedor enviar dados do PHP para o JavaScript.&#x20;

O que quer que seja colocado dentro deste objeto, será codificado como JSON dentro do objeto MapasCulturais no JavaScript.

O código abaixo pode ser executado em método do tema ou nos arquivos de layout, visões ou template:

```php
$this->jsObject['meuArray'] = [1,2,3,4];
$this->jsObject['meuObjeto'] = [
   'id' => 13,
   'name' => 'Fulano de Tal'
];
```

No JavaScript chegará:

```javascript
MapasCulturais.meuArray = [1,2,3,4];
MapasCulturais.meuObjeto = {"id": 13, "name": "Fulano de Tal"};
```

### Funções addToJs (BaseV1)

As funções ***addToJs*** adicionam ao `jsObject` dados que os scripts precisam para funcionar.

* `addEntityToJs`: Cria a chave `entity` com a seguinte estrutura para a entidade passada como parâmetro:&#x20;

```javascript
{ 
"id: 11, //id da entidade 
"ownerId": 11, // id do owner da entidade 
"ownerUserId": 5, // id do usuário proprietário pela entidade 
"definition": {}, // definição da entidade 
"userHasControl": true, // se o usuário autenticado tem controle sobre a entidade 
"canUserChangeOwner": false, // se o usuário autenticado pode mudar o proprietário da entidade 
"canUserCreateRelatedAgentsWithControl": true, // se o usuário autenticado pode definir administradores da entidade 
"status": 0, // status da entidade 
"object": {} // json_serialize da entidade 
}
```

* `addEntityTypesToJs`: Cria a chave `entityTypes` com a lista de tipos da entidade passada como parâmetro;
* `addOccurrenceFrequenciesToJs`: Cria a chave `frequencies` com as opções de frequência para as ocorrências de evento;
* `addTaxonoyTermsToJs`: Adiciona uma lista com os termos da taxonomia informada dentro da chave `taxonomyTerms`;
* `addRelatedAgentsToJs`: Adiciona a lista de agentes relacionados à chave `agentRelations` dentro da chave `entity`;
* `addRelatedAdminAgentsToJs`: Adiciona a lista dos agentes relacionados com controle sobre a entidade à chave `agentAdminRelations` dentro da chave `entity`;
* `addSubsiteAdminsToJs`: Adiciona os administradores e super administradores às chaves `admins` e `superAdmins` dentro da chave `entity`.

## Localização

Para localizar os textos dos templates, utiliza-se as funções da classe [MapasCulturais\i](https://github.com/mapasculturais/mapasculturais/blob/master/src/protected/application/lib/MapasCulturais/i.php):

```php
<?php use MapasCulturais\i; >
<p><?php i::_e("Um texto que pode ser traduzido")?></p>
<p><?php echo i::__("Outro texto que pode ser traduzido")?></p>
```

Já para localizar strings utilizadas por componentes JavaScript, utiliza-se o método `localizeScript`, da maneira demonstrada abaixo:

```php
//$this é instância do tema ativo
$this->localizeScript('minhaFuncionalidade', [
               'correctErrors' => i::__('Corrija os erros indicados abaixo.'),
               'unexpectedError' => \MapasCulturais\i::__('Erro inesperado.'),
               'Erro'=> \MapasCulturais\i::__('Erro')
]);
```

O trecho acima criará a seguinte estrutura no JavaScript e dessa maneira os scripts do JavaScript podem utilizar os textos traduzidos:

```javascript
MapasCulturais.gettext.minhaFuncionalidade = {
   "correctErrors": "Corrija os erros indicados abaixo.",
   "unexpectedError": "Erro inesperado.",
   'Erro': "Erro"
}
```

## Herança - Estendendo um Tema

@todo
