commit 0e839574ab88fb8d407a1aa53a9aa522f9135ae2
Author: Quintino A. G. Souza
Date: Mon Feb 2 07:48:36 2026 -0300
Initial commit
Módulo site_tools com ferramentas utilitárias para outros módulos:
- Bloco ShareLinks para compartilhamento em redes sociais
- Seção "Local Modules" no menu de configuração do Drupal
Co-Authored-By: Claude Opus 4.5
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e1431ef
--- /dev/null
+++ b/README.md
@@ -0,0 +1,37 @@
+# Site Tools
+
+Módulo Drupal com ferramentas utilitárias reutilizáveis para outros módulos do site.
+
+## Funcionalidades
+
+- **Menu de configuração "Local Modules"**: Fornece uma seção centralizada em `/admin/config/local-modules` para configurações de módulos desenvolvidos internamente.
+
+## Requisitos
+
+- Drupal 10.3+ ou 11
+
+## Instalação
+
+1. Coloque o módulo no diretório `modules/custom/`
+2. Ative o módulo via Drush: `drush en site_tools`
+3. Limpe o cache: `drush cr`
+
+## Uso
+
+Outros módulos podem usar a seção "Local Modules" adicionando em seus arquivos `.links.menu.yml`:
+
+```yaml
+meu_modulo.settings:
+ title: 'Meu Módulo'
+ description: 'Configurações do meu módulo'
+ route_name: meu_modulo.settings
+ parent: site_tools.admin_config
+ weight: 10
+```
+
+E declarando a dependência em `.info.yml`:
+
+```yaml
+dependencies:
+ - site_tools
+```
diff --git a/css/share-links.css b/css/share-links.css
new file mode 100644
index 0000000..516b8d0
--- /dev/null
+++ b/css/share-links.css
@@ -0,0 +1,56 @@
+/**
+ * @file
+ * Estilos para o bloco de links de compartilhamento.
+ */
+
+.site-tools-share-links {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ padding: 0.5rem 0;
+ border-bottom: 1px solid #e0e0e0;
+ margin-bottom: 1rem;
+}
+
+.site-tools-share-links__label {
+ font-size: 0.875rem;
+ font-weight: 600;
+ color: #666;
+}
+
+.site-tools-share-links__items {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ flex-wrap: wrap;
+}
+
+.site-tools-share-links__item {
+ display: inline-flex;
+ align-items: center;
+}
+
+/* Links dentro do container */
+.site-tools-share-links a {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.25rem;
+ padding: 0.25rem 0.5rem;
+ font-size: 0.875rem;
+ color: #555;
+ text-decoration: none;
+ border-radius: 4px;
+ transition: background-color 0.2s, color 0.2s;
+}
+
+.site-tools-share-links a:hover,
+.site-tools-share-links a:focus {
+ background-color: #f0f0f0;
+ color: #333;
+}
+
+/* Quando usado com AddToAny ou similar */
+.site-tools-share-links .addtoany_share_save_container {
+ display: inline-flex;
+ align-items: center;
+}
diff --git a/docs/share-links.md b/docs/share-links.md
new file mode 100644
index 0000000..0ab57a6
--- /dev/null
+++ b/docs/share-links.md
@@ -0,0 +1,256 @@
+# Share Links Block
+
+O módulo Site Tools fornece um bloco de compartilhamento (`Share Links`) que exibe links para compartilhar o conteúdo atual em redes sociais ou outros canais.
+
+O bloco funciona como um **container de design** que coleta e exibe links fornecidos por outros módulos através de hooks.
+
+## Instalação
+
+1. Copie o módulo para `modules/custom/site_tools`
+2. Ative o módulo: `drush en site_tools`
+3. Posicione o bloco "Share Links" na região desejada em `/admin/structure/block`
+
+## Fornecendo Links de Compartilhamento
+
+Para adicionar links ao bloco, implemente `hook_site_tools_share_links()` no seu módulo.
+
+### Estrutura do Hook
+
+```php
+/**
+ * Implements hook_site_tools_share_links().
+ */
+function meu_modulo_site_tools_share_links(): array {
+ $links = [];
+
+ // Cada link é identificado por uma chave única.
+ $links['minha_rede'] = [
+ // Obrigatório: render array ou markup HTML.
+ 'content' => [
+ '#type' => 'link',
+ '#title' => t('Compartilhar'),
+ '#url' => \Drupal\Core\Url::fromUri('https://exemplo.com/share'),
+ ],
+ // Opcional: peso para ordenação (menor = aparece primeiro).
+ 'weight' => 0,
+ // Opcional: identificação do módulo provedor.
+ 'provider' => 'meu_modulo',
+ ];
+
+ return $links;
+}
+```
+
+### Exemplo: Link de Email
+
+```php
+/**
+ * Implements hook_site_tools_share_links().
+ */
+function meu_modulo_site_tools_share_links(): array {
+ $request = \Drupal::request();
+ $current_url = $request->getUri();
+
+ // Obtém o título da página atual.
+ $title = \Drupal::service('title_resolver')->getTitle(
+ $request,
+ \Drupal::routeMatch()->getRouteObject()
+ );
+
+ return [
+ 'email' => [
+ 'content' => [
+ '#type' => 'link',
+ '#title' => t('Email'),
+ '#url' => \Drupal\Core\Url::fromUri('mailto:', [
+ 'query' => [
+ 'subject' => $title,
+ 'body' => t('Confira este conteúdo: @url', ['@url' => $current_url]),
+ ],
+ ]),
+ '#attributes' => [
+ 'class' => ['share-link', 'share-link--email'],
+ 'title' => t('Compartilhar por email'),
+ ],
+ ],
+ 'weight' => 100,
+ 'provider' => 'meu_modulo',
+ ],
+ ];
+}
+```
+
+### Exemplo: Integração com AddToAny
+
+```php
+/**
+ * Implements hook_site_tools_share_links().
+ */
+function meu_modulo_site_tools_share_links(): array {
+ // Verifica se o módulo AddToAny está disponível.
+ if (!\Drupal::moduleHandler()->moduleExists('addtoany')) {
+ return [];
+ }
+
+ // Renderiza o bloco do AddToAny.
+ $block_manager = \Drupal::service('plugin.manager.block');
+ $plugin_block = $block_manager->createInstance('addtoany_block', []);
+ $render = $plugin_block->build();
+
+ return [
+ 'addtoany' => [
+ 'content' => $render,
+ 'weight' => 0,
+ 'provider' => 'addtoany',
+ ],
+ ];
+}
+```
+
+### Exemplo: Links Manuais para Redes Sociais
+
+```php
+/**
+ * Implements hook_site_tools_share_links().
+ */
+function meu_modulo_site_tools_share_links(): array {
+ $current_url = \Drupal::request()->getUri();
+ $encoded_url = urlencode($current_url);
+
+ $title = \Drupal::service('title_resolver')->getTitle(
+ \Drupal::request(),
+ \Drupal::routeMatch()->getRouteObject()
+ );
+ $encoded_title = urlencode($title ?? '');
+
+ return [
+ 'facebook' => [
+ 'content' => [
+ '#type' => 'link',
+ '#title' => t('Facebook'),
+ '#url' => \Drupal\Core\Url::fromUri(
+ "https://www.facebook.com/sharer/sharer.php?u={$encoded_url}"
+ ),
+ '#attributes' => [
+ 'class' => ['share-link', 'share-link--facebook'],
+ 'target' => '_blank',
+ 'rel' => 'noopener',
+ ],
+ ],
+ 'weight' => 0,
+ ],
+ 'twitter' => [
+ 'content' => [
+ '#type' => 'link',
+ '#title' => t('X (Twitter)'),
+ '#url' => \Drupal\Core\Url::fromUri(
+ "https://twitter.com/intent/tweet?url={$encoded_url}&text={$encoded_title}"
+ ),
+ '#attributes' => [
+ 'class' => ['share-link', 'share-link--twitter'],
+ 'target' => '_blank',
+ 'rel' => 'noopener',
+ ],
+ ],
+ 'weight' => 1,
+ ],
+ 'whatsapp' => [
+ 'content' => [
+ '#type' => 'link',
+ '#title' => t('WhatsApp'),
+ '#url' => \Drupal\Core\Url::fromUri(
+ "https://api.whatsapp.com/send?text={$encoded_title}%20{$encoded_url}"
+ ),
+ '#attributes' => [
+ 'class' => ['share-link', 'share-link--whatsapp'],
+ 'target' => '_blank',
+ 'rel' => 'noopener',
+ ],
+ ],
+ 'weight' => 2,
+ ],
+ ];
+}
+```
+
+## Alterando Links de Outros Módulos
+
+Use `hook_site_tools_share_links_alter()` para modificar ou remover links fornecidos por outros módulos.
+
+```php
+/**
+ * Implements hook_site_tools_share_links_alter().
+ */
+function meu_modulo_site_tools_share_links_alter(array &$links): void {
+ // Remove um link específico.
+ unset($links['twitter']);
+
+ // Altera o peso de um link.
+ if (isset($links['facebook'])) {
+ $links['facebook']['weight'] = -10;
+ }
+
+ // Modifica atributos de um link.
+ if (isset($links['email']['content']['#attributes'])) {
+ $links['email']['content']['#attributes']['class'][] = 'minha-classe';
+ }
+}
+```
+
+## Personalizando o Template
+
+O bloco usa o template `site-tools-share-links.html.twig`. Para sobrescrevê-lo no seu tema:
+
+1. Copie `templates/site-tools-share-links.html.twig` para o diretório `templates/` do seu tema
+2. Limpe o cache: `drush cr`
+
+### Variáveis Disponíveis
+
+| Variável | Descrição |
+|----------|-----------|
+| `links` | Array de links de compartilhamento |
+| `links[key].content` | Render array do link |
+| `links[key].weight` | Peso para ordenação |
+| `links[key].provider` | Módulo que forneceu o link |
+| `attributes` | Atributos HTML do container |
+
+### Exemplo de Template Customizado
+
+```twig
+{% if links %}
+
+
{{ 'Compartilhe:'|t }}
+
+ {% for key, link in links %}
+ -
+ {{ link.content }}
+
+ {% endfor %}
+
+
+{% endif %}
+```
+
+## CSS
+
+O módulo inclui estilos básicos em `css/share-links.css`. As classes disponíveis são:
+
+| Classe | Elemento |
+|--------|----------|
+| `.site-tools-share-links` | Container principal |
+| `.site-tools-share-links__label` | Label "Share:" |
+| `.site-tools-share-links__items` | Container dos links |
+| `.site-tools-share-links__item` | Wrapper de cada link |
+| `.site-tools-share-links__item--{key}` | Modificador por tipo de link |
+
+## Cache
+
+O bloco possui cache que varia por URL (`url.path`). Se você precisar invalidar o cache programaticamente:
+
+```php
+\Drupal\Core\Cache\Cache::invalidateTags(['site_tools_share_links']);
+```
+
+## Referência da API
+
+Consulte `site_tools.api.php` para documentação completa dos hooks.
diff --git a/site_tools.api.php b/site_tools.api.php
new file mode 100644
index 0000000..a72a591
--- /dev/null
+++ b/site_tools.api.php
@@ -0,0 +1,99 @@
+getUri();
+ $current_title = \Drupal::service('title_resolver')->getTitle(
+ \Drupal::request(),
+ \Drupal::routeMatch()->getRouteObject()
+ );
+
+ $links['email'] = [
+ 'content' => [
+ '#type' => 'link',
+ '#title' => t('Share via Email'),
+ '#url' => \Drupal\Core\Url::fromUri('mailto:', [
+ 'query' => [
+ 'subject' => $current_title,
+ 'body' => $current_url,
+ ],
+ ]),
+ '#attributes' => [
+ 'class' => ['share-link', 'share-link--email'],
+ ],
+ ],
+ 'weight' => 10,
+ 'provider' => 'my_module',
+ ];
+
+ // Exemplo: integração com AddToAny.
+ // Se o módulo addtoany estiver instalado, você pode renderizar
+ // seu bloco ou widget aqui.
+ if (\Drupal::moduleHandler()->moduleExists('addtoany')) {
+ $links['addtoany'] = [
+ 'content' => [
+ '#type' => 'markup',
+ '#markup' => '' .
+ '
',
+ ],
+ 'weight' => 0,
+ 'provider' => 'addtoany',
+ ];
+ }
+
+ return $links;
+}
+
+/**
+ * Altera os links de compartilhamento coletados.
+ *
+ * @param array $links
+ * Array de links de compartilhamento coletados via
+ * hook_site_tools_share_links().
+ *
+ * @see hook_site_tools_share_links()
+ */
+function hook_site_tools_share_links_alter(array &$links): void {
+ // Exemplo: remover um link específico.
+ unset($links['email']);
+
+ // Exemplo: alterar o peso de um link.
+ if (isset($links['addtoany'])) {
+ $links['addtoany']['weight'] = -10;
+ }
+}
+
+/**
+ * @} End of "addtogroup hooks".
+ */
diff --git a/site_tools.info.yml b/site_tools.info.yml
new file mode 100644
index 0000000..f0fd175
--- /dev/null
+++ b/site_tools.info.yml
@@ -0,0 +1,5 @@
+name: Site Tools
+type: module
+description: 'Ferramentas utilitárias reutilizáveis para outros módulos do site.'
+core_version_requirement: ^10.3 || ^11
+package: Custom
diff --git a/site_tools.libraries.yml b/site_tools.libraries.yml
new file mode 100644
index 0000000..0e2692e
--- /dev/null
+++ b/site_tools.libraries.yml
@@ -0,0 +1,5 @@
+share_links:
+ version: 1.x
+ css:
+ component:
+ css/share-links.css: {}
diff --git a/site_tools.links.menu.yml b/site_tools.links.menu.yml
new file mode 100644
index 0000000..bd72ff0
--- /dev/null
+++ b/site_tools.links.menu.yml
@@ -0,0 +1,6 @@
+site_tools.admin_config:
+ title: 'Local Modules'
+ description: 'Configurações de módulos locais desenvolvidos internamente'
+ route_name: site_tools.admin_config
+ parent: system.admin_config
+ weight: 99
diff --git a/site_tools.module b/site_tools.module
new file mode 100644
index 0000000..709717f
--- /dev/null
+++ b/site_tools.module
@@ -0,0 +1,59 @@
+' . t('Site Tools provides reusable utilities for other modules, including a share links block.') . '
';
+ }
+ return NULL;
+}
+
+/**
+ * Implements hook_theme().
+ */
+function site_tools_theme(): array {
+ return [
+ 'site_tools_share_links' => [
+ 'variables' => [
+ 'links' => [],
+ 'attributes' => [],
+ ],
+ 'template' => 'site-tools-share-links',
+ ],
+ ];
+}
+
+/**
+ * Invoca hook_site_tools_share_links() para coletar links de compartilhamento.
+ *
+ * @return array
+ * Array de links de compartilhamento fornecidos por outros módulos.
+ * Cada link deve ter as chaves:
+ * - 'content': Render array ou markup do link.
+ * - 'weight': (opcional) Peso para ordenação.
+ * - 'provider': (opcional) Nome do módulo que fornece o link.
+ */
+function site_tools_collect_share_links(): array {
+ $links = \Drupal::moduleHandler()->invokeAll('site_tools_share_links');
+ \Drupal::moduleHandler()->alter('site_tools_share_links', $links);
+
+ // Ordena por peso.
+ uasort($links, function ($a, $b) {
+ $weight_a = $a['weight'] ?? 0;
+ $weight_b = $b['weight'] ?? 0;
+ return $weight_a <=> $weight_b;
+ });
+
+ return $links;
+}
diff --git a/site_tools.routing.yml b/site_tools.routing.yml
new file mode 100644
index 0000000..635eb4a
--- /dev/null
+++ b/site_tools.routing.yml
@@ -0,0 +1,7 @@
+site_tools.admin_config:
+ path: '/admin/config/local-modules'
+ defaults:
+ _controller: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage'
+ _title: 'Local Modules'
+ requirements:
+ _permission: 'access administration pages'
diff --git a/src/Plugin/Block/ShareLinksBlock.php b/src/Plugin/Block/ShareLinksBlock.php
new file mode 100644
index 0000000..2c29354
--- /dev/null
+++ b/src/Plugin/Block/ShareLinksBlock.php
@@ -0,0 +1,64 @@
+ 'site_tools_share_links',
+ '#links' => $links,
+ '#attributes' => [
+ 'class' => ['site-tools-share-links'],
+ ],
+ '#attached' => [
+ 'library' => ['site_tools/share_links'],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheContexts(): array {
+ // Cache varia por URL pois os links dependem do conteúdo atual.
+ return array_merge(parent::getCacheContexts(), ['url.path']);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheTags(): array {
+ // Permite que módulos invalidem o cache quando necessário.
+ return array_merge(parent::getCacheTags(), ['site_tools_share_links']);
+ }
+
+}
diff --git a/templates/site-tools-share-links.html.twig b/templates/site-tools-share-links.html.twig
new file mode 100644
index 0000000..75dc9c2
--- /dev/null
+++ b/templates/site-tools-share-links.html.twig
@@ -0,0 +1,25 @@
+{#
+/**
+ * @file
+ * Template para o bloco de links de compartilhamento.
+ *
+ * Variáveis disponíveis:
+ * - links: Array de links de compartilhamento, cada um contendo:
+ * - content: Render array ou markup do link.
+ * - weight: Peso para ordenação.
+ * - provider: Módulo que fornece o link.
+ * - attributes: Atributos HTML do container.
+ */
+#}
+{% if links %}
+
+{% endif %}