# 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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mapasculturais.gitbook.io/documentacao-para-desenvolvedores/formacao-para-desenvolvedores/backend-dos-temas.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
