{"id":233664,"date":"2023-02-19T17:36:00","date_gmt":"2023-02-19T14:36:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233664"},"modified":"2022-11-11T08:42:28","modified_gmt":"2022-11-11T05:42:28","slug":"criar-bloco-personalizado-do-gutenberg-parte-9-blocos-dinamicos-e-renderizacao-do-php","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/criar-bloco-personalizado-do-gutenberg-parte-9-blocos-dinamicos-e-renderizacao-do-php\/","title":{"rendered":"Criar bloco personalizado do Gutenberg &#8211; Parte 9: blocos din\u00e2micos e renderiza\u00e7\u00e3o do PHP"},"content":{"rendered":"\n<p>At\u00e9 agora, renderizamos a sa\u00edda do bloco em Javascript. No entanto, com conte\u00fado din\u00e2mico como postagens recentes ou exibindo uma postagem, precisamos renderizar a sa\u00edda do bloco em PHP. Neste post vamos aprender como e por qu\u00ea.<\/p>\n<h2>Por que precisamos lidar com blocos din\u00e2micos de maneira diferente?<\/h2>\n<p>Alguns exemplos s\u00e3o \u00f3bvios; um bloco que exibe as \u00faltimas postagens em uma categoria \u00e9 din\u00e2mico porque as postagens mudam com o tempo. Voc\u00ea n\u00e3o escolhe os posts no bloco; em vez disso, voc\u00ea provavelmente ter\u00e1 configura\u00e7\u00f5es para escolher a categoria, quais informa\u00e7\u00f5es mostrar para cada postagem, o n\u00famero de postagens, o n\u00famero de colunas e assim por diante. Toda vez que o WordPress carrega um post com este bloco, ele precisa consultar o WordPress naquele momento para os posts mais recentes. Visualizar a mesma postagem no m\u00eas seguinte pode gerar resultados diferentes, mesmo que a postagem com o bloco em si n\u00e3o tenha sido atualizada.<\/p>\n<p>Mas a necessidade de blocos din\u00e2micos \u00e0s vezes n\u00e3o \u00e9 t\u00e3o \u00f3bvia. Voc\u00ea pode imaginar um bloco de postagem em destaque onde voc\u00ea escolhe um post espec\u00edfico para exibi-lo, n\u00e3o \u00e9 necessariamente din\u00e2mico. Mas pode ser \u2013 e deve ser. Lembre-se de que a postagem selecionada pode atualizar seu t\u00edtulo, trecho ou imagem em destaque a qualquer momento \u2013 e isso deve ser refletido nos blocos que apresentam esta postagem.<\/p>\n<p>Para fazer um bloco n\u00e3o din\u00e2mico para mostrar uma \u00fanica postagem, voc\u00ea precisar\u00e1 salvar o ID da postagem, sua URL, URL da imagem em destaque, sequ\u00eancia de trechos ou o que for necess\u00e1rio para visualizar a postagem nos atributos do bloco. E aqui reside o problema. Se voc\u00ea atualizar a imagem em destaque da postagem selecionada, a postagem com o bloco de postagem em destaque n\u00e3o atualizar\u00e1 automaticamente seus atributos. Ele ficar\u00e1 salvo com o URL da imagem em destaque antiga. Somente quando voc\u00ea editar o post com o bloco, e certificar-se de que ele salva novamente os atributos com as informa\u00e7\u00f5es atualizadas, o bloco mostrar\u00e1 as informa\u00e7\u00f5es atualizadas corretas.<\/p>\n<p>Portanto, sempre que lidamos com conte\u00fado din\u00e2mico \u2013 postagens, categorias ou qualquer coisa que possa mudar com o tempo \u2013 estamos lidando com blocos din\u00e2micos. E para blocos din\u00e2micos, precisamos usar PHP \u2013 c\u00f3digo do lado do servidor \u2013 para renderizar nosso bloco para garantir que ele recuperar\u00e1 informa\u00e7\u00f5es atualizadas toda vez que renderizar.<\/p>\n<h2>A natureza alterada dos blocos din\u00e2micos no editor<\/h2>\n<p>Quando voc\u00ea come\u00e7ar a desenvolver blocos din\u00e2micos, a natureza do seu bloco dentro do editor mudar\u00e1. A fun\u00e7\u00e3o do seu bloco <code>edit<\/code>geralmente precisa ser din\u00e2mica tamb\u00e9m. Por exemplo, para um bloco de postagem em destaque, voc\u00ea precisar\u00e1 buscar postagens para escolher ou, para um bloco de not\u00edcias mais recente, precisar\u00e1 recuperar uma lista de categorias para o usu\u00e1rio escolher.<\/p>\n<p>\u00c9 totalmente poss\u00edvel solicitar informa\u00e7\u00f5es do WordPress de dentro do editor fazendo solicita\u00e7\u00f5es AJAX \u2013 seja usando pacotes e componentes ou executando-os manualmente com a <a href=\"https:\/\/developer.wordpress.org\/rest-api\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">API REST do WordPress<\/a>. Independentemente do m\u00e9todo que voc\u00ea usar, seu bloco precisa lidar com o fluxo ass\u00edncrono de entrada &#8211; o per\u00edodo de tempo enquanto aguarda uma resposta.<\/p>\n<p>Existem v\u00e1rios m\u00e9todos e padr\u00f5es para criar um bloco din\u00e2mico para Gutenberg. Mais comumente, voc\u00ea usar\u00e1 um padr\u00e3o React chamado <a href=\"https:\/\/reactjs.org\/docs\/higher-order-components.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">componentes de ordem superior,<\/a> nos quais o WordPress fornece muitas fun\u00e7\u00f5es e componentes.<\/p>\n<p>Veremos como buscar postagens e como recuperar categorias em nosso bloco na pr\u00f3xima parte do tutorial. Por enquanto precisamos aprender como fazer o PHP renderizar nosso bloco.<\/p>\n<h2>Preparando nosso bloco para renderiza\u00e7\u00e3o em PHP<\/h2>\n<p>A parte principal que precisamos fazer em Javascript \u00e9 fazer a <code>save<\/code>fun\u00e7\u00e3o do bloco retornar <code>null<\/code>. Voc\u00ea pode manter a sa\u00edda original, mas assim que dissermos ao WordPress para usar PHP para renderizar o bloco, isso ser\u00e1 ignorado. Para deixar claro para n\u00f3s e para os outros que a sa\u00edda do bloco n\u00e3o \u00e9 tratada em Javascript, vamos alterar a <code>save<\/code>fun\u00e7\u00e3o.<\/p>\n<pre><code>registerBlockType('awp\/firstblock', {\n    title: __('My first block', 'awhitepixel'), \n    category: 'common',\n    ...\n    edit: FirstBlockEdit,\n    save:() =&gt; { return null }\n});<\/code><\/pre>\n<p>N\u00e3o esque\u00e7a que alterar a fun\u00e7\u00e3o salvar far\u00e1 com que todos os blocos existentes sejam quebrados. Adicione novamente o bloco. O bloco deve funcionar como antes; com as configura\u00e7\u00f5es e atualizando os atributos. Ele agora simplesmente n\u00e3o produzir\u00e1 nada no frontend. O bloco de coment\u00e1rios estar\u00e1 l\u00e1, armazenando todos os atributos em JSON, mas nenhum HTML vis\u00edvel ser\u00e1 renderizado.<\/p>\n<p>No entanto; se algum de seus atributos estiver usando a <code>source<\/code>propriedade, voc\u00ea precisar\u00e1 alterar isso. Isso n\u00e3o \u00e9 suportado com blocos que s\u00e3o renderizados com PHP porque eles s\u00e3o analisados \u200b\u200bdiretamente da sa\u00edda do save \u2013 que agora retornamos <code>null<\/code>. Usamos source no segundo <code>RichText<\/code>em nosso bloco \u2013 para o par\u00e1grafo. Neste ponto, o editor n\u00e3o salvar\u00e1 o que voc\u00ea colocar <code>RichText<\/code>nele.<\/p>\n<p>Portanto, se voc\u00ea ainda estiver usando <code>source<\/code>o <code>myRichText<\/code>atributo, precisamos remover as propriedades <code>source<\/code>e <code>selector<\/code>para garantir que os atributos sejam armazenados e n\u00e3o analisados \u200b\u200bda <code>save<\/code>fun\u00e7\u00e3o:<\/p>\n<pre><code>attributes: {\n    ...\n    myRichText: {\n        type: 'string',\n    },\n    ...<\/code><\/pre>\n<p>Depois disso nosso bloco est\u00e1 pronto para renderiza\u00e7\u00e3o em PHP. Podemos deixar os arquivos Javascript (n\u00e3o esque\u00e7a de compilar) e o resto \u00e9 feito em PHP.<\/p>\n<h2>Renderizando blocos em PHP<\/h2>\n<p>Para dizer ao WordPress para renderizar a sa\u00edda do bloco em PHP, adicionamos um novo argumento \u00e0 fun\u00e7\u00e3o <code>register_block_type()<\/code>. Precisamos adicionar a chave <code>render_callback<\/code>ao array com um valor da fun\u00e7\u00e3o que deve ser executada.<\/p>\n<pre><code>add_action('init', function() {\n    register_block_type('awp\/firstblock', [\n        'editor_script' =&gt; 'awp-myfirstblock-js',\n        'render_callback' =&gt; 'awp_myfirstblock_render'\n    ]);\n});<\/code><\/pre>\n<h3>A fun\u00e7\u00e3o de renderiza\u00e7\u00e3o do PHP<\/h3>\n<p>Vamos definir a fun\u00e7\u00e3o <code>awp_myfirstblock_render<\/code>mais abaixo <code>functions.php<\/code>(ou onde quer que voc\u00ea tenha colocado seu c\u00f3digo PHP). Nossa fun\u00e7\u00e3o receber\u00e1 dois par\u00e2metros; vamos cham\u00e1-los <code>$attr<\/code>e <code>$content<\/code>.<\/p>\n<pre><code>function awp_myfirstblock_render($attr, $content) {\n    \/\/ return the block's output here\n}<\/code><\/pre>\n<p>O par\u00e2metro <code>$attr<\/code>ser\u00e1 um array associativo com todos os atributos salvos. O segundo par\u00e2metro, <code>$content<\/code>, \u00e9 para blocos dentro do nosso bloco. Isso \u00e9 relevante apenas para blocos que suportam blocos aninhados \u2013 o que, por exemplo, Colunas ou Capa fazem.<\/p>\n<p>A fun\u00e7\u00e3o nunca deve <code>echo<\/code>sair nada. Toda a sa\u00edda deve ser retornada, ent\u00e3o voc\u00ea precisa construir uma string e devolv\u00ea-la no final.<\/p>\n<p>Algo importante a ser lembrado sobre os atributos \u00e9 que apenas os atributos salvos aparecer\u00e3o no primeiro par\u00e2metro da fun\u00e7\u00e3o. Se um atributo nunca foi realmente alterado e salvo \u2013 ou seja, apenas confiando em seu <code>default<\/code>, o atributo n\u00e3o ser\u00e1 inclu\u00eddo em nossa fun\u00e7\u00e3o PHP.<\/p>\n<p>Voc\u00ea precisa lidar com esse problema sempre verificando <code>if (isset($attr['...']))<\/code>ou da maneira prefer\u00edvel: definindo os atributos em nossa <code>register_block_type()<\/code>chamada. Podemos fornecer outra chave, <code>attributes<\/code>, e definir seu valor para um array com todos os atributos que desejamos extrair do nosso bloco. A estrutura deve ser id\u00eantica \u00e0 que voc\u00ea definiu em Javascript, mas em vez de um objeto Javascript voc\u00ea precisa dele em um array PHP. Isso pode ser um pouco complicado para redefinir os mesmos atributos, mas com um editor de c\u00f3digo inteligente deve ser bem r\u00e1pido copiar + colar e editar em v\u00e1rias linhas em PHP.<\/p>\n<h3>Adicionando os atributos para nossa fun\u00e7\u00e3o de renderiza\u00e7\u00e3o<\/h3>\n<p>Vamos adicionar o novo <code>attributes<\/code>elemento <code>register_block_type()<\/code>e colar exatamente os mesmos atributos que definimos em nosso arquivo Javascript:<\/p>\n<pre><code>add_action('init', function() {\n    register_block_type('awp\/firstblock', [\n        'editor_script' =&gt; 'awp-myfirstblock-js',\n        'render_callback' =&gt; 'awp_myfirstblock_render',\n        'attributes' =&gt; [\n            'myRichHeading' =&gt; [\n                'type' =&gt; 'string'\n            ],\n            'myRichText' =&gt; [\n                'type' =&gt; 'string'\n            ],\n            'textAlignment' =&gt; [\n                'type' =&gt; 'string',\n            ],\n            'toggle' =&gt; [\n                'type' =&gt; 'boolean',\n                'default' =&gt; true\n            ],\n            'favoriteAnimal' =&gt; [\n                'type' =&gt; 'string',\n                'default' =&gt; 'dogs'\n            ],\n            'favoriteColor' ==&gt; [\n                'type' =&gt; 'string',\n                'default' =&gt; '#DDDDDD'\n            ],\n            'activateLasers' =&gt; [\n                'type' =&gt; 'boolean',\n                'default' =&gt; false\n            ],\n        ]\n    ]);\n});\n\u00a0\nfunction awp_myfirstblock_render($attr, $content) {\n    return '&lt;div&gt;'.$attr['favoriteColor'].'&lt;\/div&gt;';\n}<\/code><\/pre>\n<p>Tenha em mente que se voc\u00ea definir a <code>default<\/code>para todos os atributos, o <code>$attr<\/code>par\u00e2metro da sua fun\u00e7\u00e3o deve sempre conter todos os atributos. Por exemplo, o atributo <code>textAlignment<\/code>acima s\u00f3 existir\u00e1 <code>$attr<\/code>se tiver sido alterado \u2013 e voc\u00ea precisar\u00e1 verificar <code>isset($attr['textAlignment'])<\/code>.<\/p>\n<p>Infelizmente, no momento, h\u00e1 duas coisas que voc\u00ea <strong>n\u00e3o vai conseguir com o PHP block render<\/strong>. Um \u00e9 o <code>className<\/code>prop \u2013 ent\u00e3o voc\u00ea precisa construir a classe de encapsulamento (se quiser) voc\u00ea mesmo. A outra \u00e9 a <code>support<\/code>propriedade para alinhamento de blocos. No momento o WordPress n\u00e3o est\u00e1 suportando esta propriedade em blocos din\u00e2micos. N\u00e3o obteremos o valor do alinhamento de bloco escolhido, a menos que o transformemos em um atributo e o tratemos manualmente em Javascript.<\/p>\n<p>Quanto \u00e0 sa\u00edda HTML da fun\u00e7\u00e3o, isso depende totalmente de voc\u00ea!<\/p>\n<h2>Solicitando renderiza\u00e7\u00e3o do PHP de dentro do editor<\/h2>\n<p>\u00c9 poss\u00edvel solicitar a renderiza\u00e7\u00e3o do PHP do nosso bloco dentro do editor. Isso \u00e9 \u00fatil se voc\u00ea quiser visualizar a sa\u00edda do bloco no editor. Podemos fazer isso com um componente chamado <code>ServerSideRender<\/code>do <code>wp.editor<\/code>pacote.<\/p>\n<p>Como adere\u00e7os, <code>ServerSideRender<\/code>voc\u00ea precisa definir todos os atributos que deseja passar. No m\u00ednimo, voc\u00ea precisa fornecer o nome do bloco para o prop <code>block<\/code>, para que o WordPress saiba qual m\u00e9todo de renderiza\u00e7\u00e3o procurar. Isso est\u00e1 dispon\u00edvel para voc\u00ea na <code>props.name<\/code>fun\u00e7\u00e3o <code>edit<\/code>. Voc\u00ea tamb\u00e9m precisa fornecer quaisquer atributos necess\u00e1rios no prop <code>attributes<\/code>. Se desejar, voc\u00ea tamb\u00e9m pode adicionar vari\u00e1veis \u200b\u200bpersonalizadas fora dos atributos aqui. Apenas tenha em mente que isso s\u00f3 funcionar\u00e1 para o editor interno, e n\u00e3o para o frontend.<\/p>\n<p>Voc\u00ea n\u00e3o pode usar <code>ServerSideRender<\/code>na fun\u00e7\u00e3o do bloco <code>save<\/code>. Sua <code>save<\/code>fun\u00e7\u00e3o ainda deve retornar <code>null<\/code>.<\/p>\n<p>Vamos implementar <code>ServerSideRender<\/code>em nosso bloco para ver na pr\u00e1tica.<\/p>\n<h3>Usando ServerSideRender para o modo de visualiza\u00e7\u00e3o\/edi\u00e7\u00e3o de bloco<\/h3>\n<p>Se voc\u00ea seguiu a etapa anterior, onde criamos uma altern\u00e2ncia de modo de visualiza\u00e7\u00e3o\/edi\u00e7\u00e3o para nosso bloco, agora podemos usar <code>ServerSideRender<\/code>para renderizar a visualiza\u00e7\u00e3o do bloco do PHP quando alternamos para o modo de visualiza\u00e7\u00e3o.<\/p>\n<p>Primeiro precisamos lembrar de desestruturar <code>ServerSideRender<\/code>no topo:<\/p>\n<pre><code>const { ServerSideRender } = wp.editor;<\/code><\/pre>\n<p>Se voc\u00ea se lembra do passo anterior, usamos os componentes <code>Disabled<\/code>e\/ou <code>Placeholder<\/code>para realizar a visualiza\u00e7\u00e3o. O problema com o uso <code>Placeholder<\/code>\u00e9 que temos um estilo indesejado aplicado \u00e0 nossa sa\u00edda. Vamos substituir <code>Placeholder<\/code>por <code>ServerSideRender<\/code>. Voc\u00ea pode optar por manter o <code>Disabled<\/code>componente, para garantir que nenhum conte\u00fado seja clic\u00e1vel ou arrast\u00e1vel.<\/p>\n<p>No c\u00f3digo para renderizar o bloco quando o atributo <code>editMode<\/code>for false, fazemos:<\/p>\n<pre><code>...\n{!this.state.editMode &amp;&amp; \n    &lt;ServerSideRender\n        block={this.props.name}\n        attributes={{ \n            myRichHeading: attributes.myRichHeading, \n            myRichText: attributes.myRichText, \n            textAlignment: attributes.textAlignment, \n            toggle: attributes.toggle, \n            favoriteAnimal: attributes.favoriteAnimal, \n            favoriteColor: attributes.favoriteColor,\n            activateLasers: attributes.activateLasers\n        }}\n    \/&gt;\n}\n...<\/code><\/pre>\n<p>Agora, nosso bot\u00e3o personalizado na barra de ferramentas renderizar\u00e1 a sa\u00edda do PHP quando mudarmos para o modo de visualiza\u00e7\u00e3o. A sa\u00edda deve ser id\u00eantica ao visualizar o post no frontend. Este \u00e9 um bom h\u00e1bito para garantir que a sa\u00edda seja id\u00eantica no editor e no frontend.<\/p>\n<h2>Exemplo: bloco din\u00e2mico mostrando uma postagem selecionada<\/h2>\n<p>A sa\u00edda em sua fun\u00e7\u00e3o de renderiza\u00e7\u00e3o PHP pode ser qualquer coisa e voc\u00ea tem acesso total a todas as fun\u00e7\u00f5es do WordPress. Suponha um bloco onde um ID de postagem ser\u00e1 salvo em um atributo. Na <code>render_callback<\/code>fun\u00e7\u00e3o PHP voc\u00ea pode consultar a postagem do ID e gerar suas informa\u00e7\u00f5es. Deve ser bastante auto-explicativo como fazer isso, mas aqui est\u00e1 um exemplo r\u00e1pido.<\/p>\n<p><strong>NB<\/strong>: Neste exemplo, simplesmente adicionaremos uma entrada de texto ao editor para inserir manualmente um ID de postagem. Esta n\u00e3o \u00e9 uma solu\u00e7\u00e3o muito intuitiva e f\u00e1cil de usar para selecionar uma postagem \u2013 mas \u00e9 isso que aprenderemos na pr\u00f3xima etapa. O foco aqui \u00e9 na parte do PHP de renderizar o post selecionado.<\/p>\n<p>Vamos adicionar um atributo <code>selectedPostId<\/code>do tipo number:<\/p>\n<pre><code>attributes: {\n    selectedPostId: {\n        type: 'number'\n    }\n}<\/code><\/pre>\n<p>E em algum lugar dentro da fun\u00e7\u00e3o do nosso bloco <code>edit<\/code>adicionamos um <code>TextControl<\/code>componente. Pode ser onde voc\u00ea quiser \u2013 dentro do bloco ou no Inspetor.<\/p>\n<pre><code>&lt;TextControl \n    label={__(\"Type in post ID\", 'awhitepixel')}\n    type=\"number\"\n    value={attributes.selectedPostId}\n    onChange={(newval) =&gt; setAttributes({ selectedPostId: parseInt(newval) })}\n\/&gt;<\/code><\/pre>\n<p>Observe que estou tomando cuidado extra para garantir que a entrada salve o atributo corretamente como um n\u00famero, convertendo-o em inteiro com <code>parseInt()<\/code>. Embora tenhamos definido o tipo prop <code>type<\/code>para <code>number<\/code>renderizar uma entrada num\u00e9rica, o valor alterado ainda \u00e9 interpretado como uma string. O WordPress n\u00e3o salvar\u00e1 seu atributo se estiver no formato errado.<\/p>\n<p>N\u00e3o se esque\u00e7a de adicionar o novo atributo ao seu <code>ServerSideRender<\/code>componente se voc\u00ea tiver um:<\/p>\n<pre><code>&lt;ServerSideRender\n    block={this.props.name}\n    attributes={{ \n        selectedPostId: attributes.selectedPostId,\n        ...<\/code><\/pre>\n<h3>A parte do PHP<\/h3>\n<p>Isso deveria ter cuidado da parte do Javascript. Vamos para o PHP. Primeiro, precisamos adicionar o novo atributo <code>selectedPostId<\/code>ao <code>attributes<\/code>array em <code>register_block_type()<\/code>:<\/p>\n<pre><code>register_block_type('awp\/firstblock', [\n    'editor_script' =&gt; 'awp-myfirstblock-js',\n    'render_callback' =&gt; 'awp_myfirstblock_render',\n    'attributes' =&gt; [\n        'selectedPostId' =&gt; [\n            'type' =&gt; 'number',\n            'default' =&gt; 0\n        ],\n        ...\n    ]\n]);<\/code><\/pre>\n<p>Na <code>render_callback<\/code>fun\u00e7\u00e3o agora podemos acessar o ID do post com <code>$attr['selectedPostId']<\/code>. Podemos com isso fazer um simples <code>get_post()<\/code>e gerar os dados do post; seu link e t\u00edtulo:<\/p>\n<pre><code>function awp_myfirstblock_render($attr, $content) {\n    $str = '';\n    if ($attr['selectedPostId'] &gt; 0) {\n        $post = get_post($attr['selectedPostId']);\n        if (!$post) {\n            return $str;\n        }\n        $str = '&lt;div class=\"awp-myfirstblock\"&gt;';\n        $str .= '&lt;a href=\"'. get_the_permalink($post). '\"&gt;';\n        $str .= '&lt;h3&gt;'. get_the_title($post). '&lt;\/h3&gt;';\n        $str .= '&lt;\/a&gt;';\n        $str .= '&lt;\/div&gt;';\n    }\n    return $str;\n}<\/code><\/pre>\n<p>Este \u00e9 um exemplo muito b\u00e1sico que serve como um trampolim para voc\u00ea escrever um c\u00f3digo mais avan\u00e7ado e personalizado.<\/p>\n<p>Agora que sabemos como lidar com a renderiza\u00e7\u00e3o de blocos din\u00e2micos, o pr\u00f3ximo passo \u00e9 aprender como tornar a parte do editor mais intuitiva tamb\u00e9m. Na pr\u00f3xima etapa, focaremos em como consultar postagens de dentro do editor de blocos e fornecer ao usu\u00e1rio uma maneira melhor de selecionar uma postagem.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Com conte\u00fado de bloco din\u00e2mico, como postagens recentes ou exibindo uma postagem, precisamos renderizar a sa\u00edda do bloco em PHP. Neste post vamos aprender como e por qu\u00ea.<\/p>\n","protected":false},"author":1,"featured_media":152680,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[898,898,941,941,1110,806,806,846,846,867,867],"tags":[1170],"class_list":["post-233664","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-gutenberg-8","category-n-a","category-php-8","category-tutoriais","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/233664","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=233664"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/233664\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/152680"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=233664"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=233664"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=233664"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}