{"id":444,"date":"2011-08-29T19:52:37","date_gmt":"2011-08-29T18:52:37","guid":{"rendered":"http:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/"},"modified":"2011-08-29T19:52:37","modified_gmt":"2011-08-29T18:52:37","slug":"internationalization-i18n-with-mojolicious-and-template-toolkit","status":"publish","type":"post","link":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/","title":{"rendered":"Internationalization (i18n) with Mojolicious and Template Toolkit"},"content":{"rendered":"<p>In a <a href=\"\/cstrep\/blog\/2011\/08\/01\/using-template-toolkit-with-mojolicious\" rel=\"nofollow\">previous post<\/a> I talked about this new <a href=\"http:\/\/mojolicio.us\" rel=\"nofollow\">Mojolicious<\/a>-based application that I&#39;ve been working on, that btw was rolled out in production today (yay!)<\/p>\n<h3>Classic I18N with TT<\/h3>\n<p>One of the required features of this app was &quot;i18n&quot;, internationalization. To be less vague, the requirement was to present the UI in different languages. We&#39;re using Template Toolkit, so our templates need to have strings marked in a special way to allow translation to kick-in at run-time. Usually in TT you do this with:<\/p>\n<pre>\r\n&lt;html&gt;\r\n&#xA0;\r\n&lt;head&gt;\r\n&lt;title&gt;<strong>[% l(&#39;This is the title of the page&#39;) %]<\/strong>&lt;\/title&gt;\r\n&lt;\/head&gt;\r\n&#xA0;\r\n&lt;body&gt;\r\n&lt;h1&gt;<strong>[% l(&#39;Hello, world!&#39;) %]<\/strong>&lt;\/h1&gt;\r\n&lt;p&gt;\r\n<strong>[% l(&#39;Some text here&#39;) %]<\/strong>\r\n&lt;\/p&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;\r\n<\/pre>\n<p>so all the strings that have to be translated according to the user language have to be marked up with:<\/p>\n<pre>\r\n[% l(&#39;&lt;your string here&gt;&#39;) %]\r\n<\/pre>\n<h3>Enter Mojolicious<\/h3>\n<p>Mojolicious includes a built-in <a href=\"https:\/\/metacpan.org\/module\/Mojolicious::Plugin::I18N\" rel=\"nofollow\">I18N<\/a> plugin that simplifies your life allowing the <code>&lt;% l(&#39;somestring)&#39; %&gt;<\/code> syntax to work. That is, it gives you a <code>l()<\/code> helper.<\/p>\n<h3>Helper?<\/h3>\n<p>A <strong>helper<\/strong> is a method that it&#39;s available both as part of your controller object, <strong>and<\/strong> within templates.<\/p>\n<h3>Back to Mojolicious&#8230;<\/h3>\n<p>In the example helper syntax I wrote <code>&lt;% l(&#39;somestring)&#39; %&gt;<\/code> because that&#39;s Mojolicious default templating system syntax. However, under Template Toolkit, <strong>you can&#39;t use that syntax!<\/strong> You have to pass through an extra level, as in:<\/p>\n<pre>\r\n&lt;!-- This is my TT template --&gt;\r\n[% c.l(&#39;&lt;your string here&gt;&#39;) %]\r\n<\/pre>\n<p>I&#39;m not exactly sure why that <code>c.<\/code> is required, but that&#39;s how it is.<\/p>\n<h3>I18N workflow: extracting the strings<\/h3>\n<p>Everything would be fantastic, except there&#39;s one tricky problem. After you worked so hard on your TT templates, now it&#39;s time to collect all the marked up strings, presumably to build a .PO file to be shipped to translation agencies or whatever system you&#39;re using for that. More on that later.<\/p>\n<p>In the Perl world, there is an equivalent of GNU xgettext, which is <code>xgettext.pl<\/code>. This tool is part of the <a href=\"https:\/\/metacpan.org\/module\/Locale::Maketext::Lexicon\" rel=\"nofollow\">Locale::Maketext::Lexicon<\/a> CPAN distribution, which is kind of &quot;the standard&quot; way to i18n in Perl. Or it is for us here anyway since we started building i18n for my.opera.com in 2008.<\/p>\n<p>The tricky problem is that even though <code>xgettext.pl<\/code> understands quite a few syntax variants, it didn&#39;t understand <code>[% c.l(&#39;string&#39;) %]<\/code>. After a few Perl debugger sessions, <strong>I managed to teach <code>Locale::Maketext::Extract::Plugin::TT2<\/code> how to parse Mojolicious-style syntax<\/strong>. I knew that Clinton Gormley, the maintainer of L::M::Lexicon had a source repository for it on Github, so <a href=\"https:\/\/github.com\/cosimo\/locale-maketext-lexicon\" rel=\"nofollow\">I forked his repository<\/a> and <a href=\"https:\/\/github.com\/cosimo\/locale-maketext-lexicon\/tree\/tt2+mojolicious\" rel=\"nofollow\">pushed my changes on a dedicated branch<\/a>.<\/p>\n<h3>CPAN, Github and the Community<\/h3>\n<p>This is where <strong>the Github + CPAN model really shines<\/strong>. You&#39;re using a CPAN module. You stumble on a problem. Fix the problem. Find its repository on Github. Fork it, push your fix, and <strong>if you&#39;re lucky<\/strong>, you have your fix merged and out on CPAN the same day.<\/p>\n<p>This is what actually happened. Clinton got in touch the very same day I sent him the pull request and later pushed out the changes on CPAN. If you ask me, that&#39;s just awesome. I wish everything worked that way :)<\/p>\n<h3>Closing the i18n workflow<\/h3>\n<p>Fixed the <code>c.l()<\/code> problem, everything else was easier. <code>xgettext.pl<\/code> allows you to collect strings from your code and templates and build a master .PO file with all the strings. Then <code>msgmerge<\/code>, a standard GNU gettext tool, allows you to take the generated master PO file and merge it with any existing language-specific PO if any. If you don&#39;t have any, just copy the master PO file (usually called POT, or reference PO file) to <code>&lt;language&gt;.po<\/code> and start translating.<\/p>\n<p>Last step is either:<\/p>\n<ul>\n<li>compiling the .po files to .mo, a lookup-optimized form of the .po file<\/li>\n<li>creating the &quot;lexicon&quot; files. In the Perl world, these are nothing more than Perl modules with a <code>%Lexicon<\/code> hash that contains all string IDs and their translations<\/li>\n<\/ul>\n<p>We&#39;re long time fans of the latter approach, so our lexicon files look like this:<\/p>\n<pre>\r\npackage AuthOpera::Locale::it;\r\n&#xA0;\r\nuse strict;\r\nuse utf8;\r\nuse base qw(AuthOpera::Locale);\r\n&#xA0;\r\n### LEXICON STARTS HERE (don&#39;t remove this line)\r\nour %Lexicon = (\r\n&#xA0;\r\n    # Automatic fallback to string ID when no translation available\r\n    _AUTO =&gt; 1,\r\n&#xA0;\r\n    # String IDs                  # Translations\r\n    &quot;Application name:&quot;        =&gt; &quot;Nome dell&#39;applicazione:&quot;,\r\n    &quot;Application registration&quot; =&gt; &quot;Registrazione dell&#39; applicazione&quot;,\r\n    &quot;Data provider:&quot;           =&gt; &quot;Provider dei dati:&quot;,\r\n&#xA0;\r\n    # ...\r\n);\r\n### LEXICON ENDS HERE\r\n&#xA0;\r\n1;\r\n<\/pre>\n<p>and we use a simple subclass of <a href=\"https:\/\/metacpan.org\/module\/Locale::PO\" rel=\"nofollow\">Locale::PO<\/a> to read the PO file in memory and write back a lexicon based on a fixed template, hence the <code>### LEXICON<\/code> lines above.<\/p>\n<h3>Transifex<\/h3>\n<p>Currently we also use <a href=\"http:\/\/www.transifex.net\" rel=\"nofollow\">Transifex<\/a>, that allows to have external translators contribute to PO files directly from a web page, and if you configure it to do so, commit straight to your source code repository. You can then trigger automated builds of the lexicon files, having completed the full i18n workflow.<\/p>\n<p>I find this system pretty simple but at the same time fully automated and very powerful. I&#39;d love to hear comments or feedback about this stuff, especially from people adopting a different process.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.streppone.it\/img\/mypost20110829.gif\" width=\"1\" height=\"1\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In a previous post I talked about this new Mojolicious-based application that I&#39;ve been working on, that btw was rolled out in production today (yay!) Classic I18N with TT One of the required features of this app was &quot;i18n&quot;, internationalization. To be less vague, the requirement was to present the UI in different languages. We&#39;re [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[49,91,285,279,280,284,51,50,278,277,283,281,282,48],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Internationalization (i18n) with Mojolicious and Template Toolkit - Random hacking<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Internationalization (i18n) with Mojolicious and Template Toolkit - Random hacking\" \/>\n<meta property=\"og:description\" content=\"In a previous post I talked about this new Mojolicious-based application that I&#039;ve been working on, that btw was rolled out in production today (yay!) Classic I18N with TT One of the required features of this app was &quot;i18n&quot;, internationalization. To be less vague, the requirement was to present the UI in different languages. We&#039;re [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/\" \/>\n<meta property=\"og:site_name\" content=\"Random hacking\" \/>\n<meta property=\"article:published_time\" content=\"2011-08-29T18:52:37+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/www.streppone.it\/img\/mypost20110829.gif\" \/>\n<meta name=\"author\" content=\"cosimo\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"cosimo\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/\"},\"author\":{\"name\":\"cosimo\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\"},\"headline\":\"Internationalization (i18n) with Mojolicious and Template Toolkit\",\"datePublished\":\"2011-08-29T18:52:37+00:00\",\"dateModified\":\"2011-08-29T18:52:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/\"},\"wordCount\":750,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\"},\"image\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/www.streppone.it\/img\/mypost20110829.gif\",\"keywords\":[\"cpan\",\"development\",\"i18n\",\"internationalization\",\"Locale::Maketext::Lexicon\",\"Locale::PO\",\"mojolicious\",\"perl\",\"PO\",\"Template Toolkit\",\"transifex\",\"TT\",\"TT2\",\"web\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/\",\"url\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/\",\"name\":\"Internationalization (i18n) with Mojolicious and Template Toolkit - Random hacking\",\"isPartOf\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/www.streppone.it\/img\/mypost20110829.gif\",\"datePublished\":\"2011-08-29T18:52:37+00:00\",\"dateModified\":\"2011-08-29T18:52:37+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#primaryimage\",\"url\":\"http:\/\/www.streppone.it\/img\/mypost20110829.gif\",\"contentUrl\":\"http:\/\/www.streppone.it\/img\/mypost20110829.gif\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.streppone.it\/cosimo\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Internationalization (i18n) with Mojolicious and Template Toolkit\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#website\",\"url\":\"https:\/\/www.streppone.it\/cosimo\/blog\/\",\"name\":\"Random hacking\",\"description\":\"Assume nothing. Code defensively. Keep it simple, stupid!\",\"publisher\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.streppone.it\/cosimo\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\",\"name\":\"cosimo\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g\",\"caption\":\"cosimo\"},\"logo\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/\"},\"url\":\"https:\/\/www.streppone.it\/cosimo\/blog\/author\/cosimo\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Internationalization (i18n) with Mojolicious and Template Toolkit - Random hacking","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/","og_locale":"en_US","og_type":"article","og_title":"Internationalization (i18n) with Mojolicious and Template Toolkit - Random hacking","og_description":"In a previous post I talked about this new Mojolicious-based application that I&#39;ve been working on, that btw was rolled out in production today (yay!) Classic I18N with TT One of the required features of this app was &quot;i18n&quot;, internationalization. To be less vague, the requirement was to present the UI in different languages. We&#39;re [&hellip;]","og_url":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/","og_site_name":"Random hacking","article_published_time":"2011-08-29T18:52:37+00:00","og_image":[{"url":"http:\/\/www.streppone.it\/img\/mypost20110829.gif"}],"author":"cosimo","twitter_card":"summary_large_image","twitter_misc":{"Written by":"cosimo","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#article","isPartOf":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/"},"author":{"name":"cosimo","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1"},"headline":"Internationalization (i18n) with Mojolicious and Template Toolkit","datePublished":"2011-08-29T18:52:37+00:00","dateModified":"2011-08-29T18:52:37+00:00","mainEntityOfPage":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/"},"wordCount":750,"commentCount":0,"publisher":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1"},"image":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#primaryimage"},"thumbnailUrl":"http:\/\/www.streppone.it\/img\/mypost20110829.gif","keywords":["cpan","development","i18n","internationalization","Locale::Maketext::Lexicon","Locale::PO","mojolicious","perl","PO","Template Toolkit","transifex","TT","TT2","web"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/","url":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/","name":"Internationalization (i18n) with Mojolicious and Template Toolkit - Random hacking","isPartOf":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#primaryimage"},"image":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#primaryimage"},"thumbnailUrl":"http:\/\/www.streppone.it\/img\/mypost20110829.gif","datePublished":"2011-08-29T18:52:37+00:00","dateModified":"2011-08-29T18:52:37+00:00","breadcrumb":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#primaryimage","url":"http:\/\/www.streppone.it\/img\/mypost20110829.gif","contentUrl":"http:\/\/www.streppone.it\/img\/mypost20110829.gif"},{"@type":"BreadcrumbList","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2011\/08\/internationalization-i18n-with-mojolicious-and-template-toolkit\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.streppone.it\/cosimo\/blog\/"},{"@type":"ListItem","position":2,"name":"Internationalization (i18n) with Mojolicious and Template Toolkit"}]},{"@type":"WebSite","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#website","url":"https:\/\/www.streppone.it\/cosimo\/blog\/","name":"Random hacking","description":"Assume nothing. Code defensively. Keep it simple, stupid!","publisher":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.streppone.it\/cosimo\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1","name":"cosimo","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g","caption":"cosimo"},"logo":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/"},"url":"https:\/\/www.streppone.it\/cosimo\/blog\/author\/cosimo\/"}]}},"_links":{"self":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts\/444"}],"collection":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/comments?post=444"}],"version-history":[{"count":0,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts\/444\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/media?parent=444"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/categories?post=444"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/tags?post=444"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}