{"id":22261,"date":"2021-01-06T17:40:49","date_gmt":"2021-01-06T17:40:49","guid":{"rendered":"http:\/\/how_to_build_an_enhanced_gravatar_service_part_2"},"modified":"2021-01-06T17:40:49","modified_gmt":"2021-01-06T17:40:49","slug":"how_to_build_an_enhanced_gravatar_service_part_2","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2","title":{"rendered":"How to Build an Enhanced Gravatar Service, Part 2"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p><a href=\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_1\">Part 1<\/a> of this post defines the capabilities of an enhanced Gravatar service, which I named Clavatar, and describes the following initial steps for building it:<\/p>\n<ol>\n<li>Set up the database.<\/li>\n<li>Establish the user-registration process.<\/li>\n<li>Install the Cloudinary PHP Library, version 2.0.0-Beta.<\/li>\n<li>Implement the image-upload operation.<\/li>\n<li>Associate images with user accounts.<\/li>\n<\/ol>\n<p>This post, part 2 of the series, explains how to make Clavatar work like Gravatar and to develop Clavatar\u2019s capabilities of enabling requests for various versions of the images related to user accounts.<\/p>\n<h2>Image Retrieval Through User Hashes<\/h2>\n<p>Recall that Gravatar retrieves user images through their hash in a URL, as in this example:<\/p>\n<p><code>https:\/\/www.gravatar.com\/avatar\/205e460b479e2e5b48aec07710c08d50<\/code><\/p>\n<p>To enable Clavatar to do the same, set up the API endpoint, as follows:<\/p>\n<p><strong>1.<\/strong> Add the following to the <code>routes\/web.php<\/code> file:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\">$router-&gt;get(<span class=\"hljs-string\">'avatar\/{hash}'<\/span>, <span class=\"hljs-string\">'AvatarController@retrieveAvatar'<\/span>);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>2.<\/strong> Add the following <code>retrieveAvatar<\/code> function to the <code>app\/Http\/Controllers\/AvatarController.php<\/code> file:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">retrieveAvatar<\/span><span class=\"hljs-params\">(Request $request, $hash)<\/span>\n    <\/span>{\n        $defaultImageTag = <span class=\"hljs-keyword\">$this<\/span>-&gt;cloudinary-&gt;imageTag(<span class=\"hljs-string\">'default'<\/span>)-&gt;serialize();\n        $defaultImageUrl = <span class=\"hljs-keyword\">$this<\/span>-&gt;cloudinary-&gt;image(<span class=\"hljs-string\">'default'<\/span>)-&gt;toUrl();\n\n        $user = User::where(<span class=\"hljs-string\">'hash'<\/span>, $hash)-&gt;first();\n\n        <span class=\"hljs-keyword\">if<\/span>(is_null($user)) {\n            <span class=\"hljs-keyword\">return<\/span> $defaultImageTag;\n        }\n\n        $publicId = $user-&gt;avatar_id;\n\n        $imageUrl = <span class=\"hljs-keyword\">$this<\/span>-&gt;cloudinary-&gt;image($publicId);\n        $imageTag = <span class=\"hljs-keyword\">$this<\/span>-&gt;cloudinary-&gt;imageTag($publicId);\n\n        <span class=\"hljs-keyword\">return<\/span> $imageTag-&gt;serialize();\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The code above does the following:<\/p>\n<ul>\n<li>\n<code>$this-&gt;cloudinary-&gt;imageTag('default')-&gt;serialize();<\/code> returns an <code>&lt;image&gt;<\/code> tag that displays an image with the public ID (<code>public_id<\/code>) <code>default<\/code>.<\/li>\n<li>\n<code>$this-&gt;cloudinary-&gt;image('default')-&gt;toUrl();<\/code> returns a link to the default image.<\/li>\n<li>\n<code>User::where('hash', $hash)-&gt;first();<\/code> checks if this hash is in the database and, if so, returns the image associated with the user account. Otherwise, the code returns the default image.<\/li>\n<\/ul>\n<div class='c-callout  c-callout--inline-title c-callout--note'><strong class='c-callout__title'>Note:<\/strong> <p>A default image is already in the database. Be sure to upload another default image to your Cloudinary account\u2019s Media Library and name it <code>default<\/code>.<\/p><\/div>\n<p><strong>3.<\/strong> Verify that everything works by running the API endpoint in a browser:<\/p>\n<ul>\n<li>\n<p>With a random hash, e.g.:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/avatar.png\" alt=\"avatar\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"445\"\/><\/p>\n<\/li>\n<li>\n<p>With a valid hash, e.g.:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/avatar_prosper.png\" alt=\"Prosper Avatar\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"445\"\/><\/p>\n<\/li>\n<\/ul>\n<p>Now Clavatar works exactly like Gravatar.<\/p>\n<h2>Implementation of Other Features<\/h2>\n<p><strong>Feature:<\/strong> Enablement of the ability to request for an image of any size by adding the <code>size<\/code> parameter, e.g., <code>s=400<\/code> or <code>size=400<\/code>, to the URL.<\/p>\n<p><strong>Implementation Step:<\/strong> Update the <code>retrieveAvatar<\/code> function, as follows:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">retrieveAvatar<\/span><span class=\"hljs-params\">(Request $request, $hash)<\/span>\n    <\/span>{\n        $defaultImageTag = <span class=\"hljs-keyword\">$this<\/span>-&gt;cloudinary-&gt;imageTag(<span class=\"hljs-string\">'default'<\/span>)-&gt;serialize();\n        $defaultImageUrl = <span class=\"hljs-keyword\">$this<\/span>-&gt;cloudinary-&gt;image(<span class=\"hljs-string\">'default'<\/span>)-&gt;toUrl();\n\n        $user = User::where(<span class=\"hljs-string\">'hash'<\/span>, $hash)-&gt;first();\n\n        <span class=\"hljs-keyword\">if<\/span>(is_null($user)) {\n            <span class=\"hljs-keyword\">return<\/span> $defaultImageTag;\n        }\n\n        $publicId = $user-&gt;avatar_id;\n\n        $imageUrl = <span class=\"hljs-keyword\">$this<\/span>-&gt;cloudinary-&gt;image($publicId);\n        $imageTag = <span class=\"hljs-keyword\">$this<\/span>-&gt;cloudinary-&gt;imageTag($publicId);\n\n        <span class=\"hljs-keyword\">if<\/span>($request-&gt;has(<span class=\"hljs-string\">'s'<\/span>) || $request-&gt;has(<span class=\"hljs-string\">'size'<\/span>)) {\n            $size = $request-&gt;query(<span class=\"hljs-string\">'s'<\/span>) ?: $request-&gt;query(<span class=\"hljs-string\">'size'<\/span>);\n\n            $imageUrl-&gt;resize(Resize::fill($size, $size));\n            $imageTag-&gt;resize(Resize::fill($size, $size));\n        } <span class=\"hljs-keyword\">else<\/span> {\n            $imageUrl-&gt;resize(Resize::fill(<span class=\"hljs-number\">100<\/span>,<span class=\"hljs-number\">100<\/span>));\n            $imageTag-&gt;resize(Resize::fill(<span class=\"hljs-number\">100<\/span>,<span class=\"hljs-number\">100<\/span>));\n        }\n\n        <span class=\"hljs-keyword\">return<\/span> $imageTag-&gt;serialize();\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>Result (Example):<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/avatar_prosper_final.png\" alt=\"Avatar results\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"445\"\/><\/p>\n<p><strong>Feature:<\/strong> Enablement of the ability to return a cartoonized version of an image by adding the <code>d=cp<\/code> parameter to the URL.<\/p>\n<p><strong>Implementation Step:<\/strong> Add the following to the <code>retrieveAvatar<\/code> function:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">retrieveAvatar<\/span><span class=\"hljs-params\">(Request $request, $hash)<\/span>\n    <\/span>{\n        \u2026.\n        \u2026.\n        <span class=\"hljs-keyword\">if<\/span>($request-&gt;has(<span class=\"hljs-string\">'d'<\/span>)) {\n            $defaultOption = $request-&gt;query(<span class=\"hljs-string\">'d'<\/span>);\n\n            <span class=\"hljs-keyword\">if<\/span>($defaultOption == <span class=\"hljs-string\">'cp'<\/span>) {\n                $imageUrl-&gt;effect(Effect::cartoonify());\n                $imageTag-&gt;effect(Effect::cartoonify());\n            }\n        }\n\n        <span class=\"hljs-keyword\">return<\/span> $imageTag-&gt;serialize();\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>Result (Example):<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/avatar_prosper_cartoonify.png\" alt=\"Avatar\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"445\"\/><\/p>\n<p><strong>Feature:<\/strong> Enablement of the ability to request for the black-and white version of an image by adding the <code>d=bw<\/code> parameter to the URL.<\/p>\n<p><strong>Implementation Step:<\/strong> Update the <code>retrieveAvatar<\/code> function, as follows:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">retrieveAvatar<\/span><span class=\"hljs-params\">(Request $request, $hash)<\/span>\n    <\/span>{\n        \u2026.\n        \u2026.\n        <span class=\"hljs-keyword\">if<\/span>($request-&gt;has(<span class=\"hljs-string\">'d'<\/span>)) {\n            $defaultOption = $request-&gt;query(<span class=\"hljs-string\">'d'<\/span>);\n\n            <span class=\"hljs-keyword\">if<\/span>($defaultOption == <span class=\"hljs-string\">'cp'<\/span>) {\n                $imageUrl-&gt;effect(Effect::cartoonify());\n                $imageTag-&gt;effect(Effect::cartoonify());\n            }\n\n           <span class=\"hljs-keyword\">if<\/span>($defaultOption == <span class=\"hljs-string\">'bw'<\/span>) {\n                $imageUrl-&gt;effect(Effect::blackWhite(<span class=\"hljs-number\">30<\/span>));\n                $imageTag-&gt;effect(Effect::blackWhite(<span class=\"hljs-number\">30<\/span>));\n            }\n\n        }\n\n        <span class=\"hljs-keyword\">return<\/span> $imageTag-&gt;serialize();\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>Result (Example):<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/avatar_bw.png\" alt=\"BW Avatar\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"445\"\/><\/p>\n<p><strong>Feature:<\/strong> Enablement of the ability to request for an artistic version of an image by adding the <code>d=hk<\/code> parameter to the URL.<\/p>\n<p><strong>Implementation Step:<\/strong> Update the <code>retrieveAvatar<\/code> function, as follows:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">retrieveAvatar<\/span><span class=\"hljs-params\">(Request $request, $hash)<\/span>\n    <\/span>{\n        \u2026.\n        \u2026.\n        <span class=\"hljs-keyword\">if<\/span>($request-&gt;has(<span class=\"hljs-string\">'d'<\/span>)) {\n            $defaultOption = $request-&gt;query(<span class=\"hljs-string\">'d'<\/span>);\n\n            <span class=\"hljs-keyword\">if<\/span>($defaultOption == <span class=\"hljs-string\">'cp'<\/span>) {\n                $imageUrl-&gt;effect(Effect::cartoonify());\n                $imageTag-&gt;effect(Effect::cartoonify());\n            }\n\n           <span class=\"hljs-keyword\">if<\/span>($defaultOption == <span class=\"hljs-string\">'bw'<\/span>) {\n                $imageUrl-&gt;effect(Effect::blackWhite(<span class=\"hljs-number\">30<\/span>));\n                $imageTag-&gt;effect(Effect::blackWhite(<span class=\"hljs-number\">30<\/span>));\n            }\n\n           <span class=\"hljs-keyword\">if<\/span>($defaultOption == <span class=\"hljs-string\">'hk'<\/span>) {\n                $imageUrl-&gt;effect(Effect::artisticFilter(ArtisticFilter::HOKUSAI));\n                $imageTag-&gt;effect(Effect::artisticFilter(ArtisticFilter::HOKUSAI));\n            }\n        }\n\n        <span class=\"hljs-keyword\">return<\/span> $imageTag-&gt;serialize();\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>Result (Example):<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/avatar_hk.png\" alt=\"Avatar hk\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"445\"\/><\/p>\n<p><strong>Feature:<\/strong> Enablement of the ability to request for the compressed and optimized version of an image by adding the <code>q=auto<\/code> parameter to the URL.<\/p>\n<p><strong>Implementation Step:<\/strong> Add the following to the <code>retrieveAvatar<\/code> function:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">retrieveAvatar<\/span><span class=\"hljs-params\">(Request $request, $hash)<\/span>\n    <\/span>{\n        \u2026.\n        \u2026.\n        \u2026.\n        \u2026.\n        <span class=\"hljs-keyword\">if<\/span>($request-&gt;has(<span class=\"hljs-string\">'q'<\/span>)) {\n            $qualityOption = $request-&gt;query(<span class=\"hljs-string\">'q'<\/span>);\n\n            <span class=\"hljs-keyword\">if<\/span>($qualityOption == <span class=\"hljs-string\">'auto'<\/span>) {\n                $imageUrl-&gt;quality(Quality::auto());\n                $imageTag-&gt;quality(Quality::auto());\n            }\n        }\n\n        <span class=\"hljs-keyword\">return<\/span> $imageTag-&gt;serialize();\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>Result (Example):<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/avatar_quality.png\" alt=\"Avatar Quality\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"445\"\/><\/p>\n<p><strong>Feature:<\/strong> Enablement of the capability to request for the best format of an image by adding the <code>f=auto<\/code> parameter to the URL. This version ensures the most suitable format for whichever browser is delivering the image.<\/p>\n<p><strong>Implementation Step:<\/strong> Add the following to the <code>retrieveAvatar<\/code> function:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">retrieveAvatar<\/span><span class=\"hljs-params\">(Request $request, $hash)<\/span>\n    <\/span>{\n        \u2026.\n        \u2026.\n        \u2026.\n        \u2026.\n        <span class=\"hljs-keyword\">if<\/span>($request-&gt;has(<span class=\"hljs-string\">'f'<\/span>)) {\n            $formatOption = $request-&gt;query(<span class=\"hljs-string\">'f'<\/span>);\n\n            <span class=\"hljs-keyword\">if<\/span>($formatOption == <span class=\"hljs-string\">'auto'<\/span>) {\n                $imageUrl-&gt;format(Format::auto());\n                $imageTag-&gt;format(Format::auto());\n            }\n        }\n\n        <span class=\"hljs-keyword\">return<\/span> $imageTag-&gt;serialize();\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>Result (Example):<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/avatar_format.png\" alt=\"Avatar Format\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"445\"\/><\/p>\n<p><strong>Feature:<\/strong> Enablement of the ability to request for the rounded-corners version of an image by adding the a <code>rc=y<\/code> parameter to the URL.<\/p>\n<p><strong>Implementation Step:<\/strong> Add the following to the <code>retrieveAvatar<\/code> function:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">retrieveAvatar<\/span><span class=\"hljs-params\">(Request $request, $hash)<\/span>\n    <\/span>{\n        \u2026.\n        \u2026.\n        \u2026.\n        \u2026.\n        <span class=\"hljs-keyword\">if<\/span>($request-&gt;has(<span class=\"hljs-string\">'rc'<\/span>)) {\n            $roundedOption = $request-&gt;query(<span class=\"hljs-string\">'rc'<\/span>);\n\n            <span class=\"hljs-keyword\">if<\/span>($roundedOption == <span class=\"hljs-string\">'y'<\/span>) {\n                $imageUrl-&gt;roundCorners(RoundCorners::max());\n                $imageTag-&gt;roundCorners(RoundCorners::max());\n            }\n        }\n\n        <span class=\"hljs-keyword\">return<\/span> $imageTag-&gt;serialize();\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>Result (Example):<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/avatar_rounded_corners.png\" alt=\"Rounded corners\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"445\"\/><\/p>\n<p><strong>Feature:<\/strong> Enablement of the ability to rotate an image by adding the <code>r=&lt;angle&gt;<\/code> parameter, e.g., <code>r=40<\/code>, to the URL. The value of the angle must be between 1 and 100.<\/p>\n<p><strong>Implementation Step:<\/strong> Add the following to the <code>retrieveAvatar<\/code> function:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">retrieveAvatar<\/span><span class=\"hljs-params\">(Request $request, $hash)<\/span>\n    <\/span>{\n        \u2026.\n        \u2026.\n        \u2026.\n        \u2026.\n        <span class=\"hljs-keyword\">if<\/span>($request-&gt;has(<span class=\"hljs-string\">'r'<\/span>)) {\n            $roundedOption = $request-&gt;query(<span class=\"hljs-string\">'r'<\/span>);\n\n            $imageUrl-&gt;rotate($roundedOption);\n            $imageTag-&gt;rotate($roundedOption);\n        }\n\n        <span class=\"hljs-keyword\">return<\/span> $imageTag-&gt;serialize();\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>Result (Example):<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/avatar_rotate.png\" alt=\"Rotate\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"445\"\/><\/p>\n<p><strong>Feature:<\/strong> Enablement of the ability to request for a color-bordered version of an image by adding the <code>b=&lt;color&gt;<\/code> parameter, e.g., <code>b=red<\/code>, to the URL.<\/p>\n<p><strong>Implementation Step:<\/strong> Add the following to the <code>retrieveAvatar<\/code> function:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php shcb-wrap-lines\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">retrieveAvatar<\/span><span class=\"hljs-params\">(Request $request, $hash)<\/span>\n    <\/span>{\n        \u2026.\n        \u2026.\n        \u2026.\n        \u2026.\n        <span class=\"hljs-keyword\">if<\/span>($request-&gt;has(<span class=\"hljs-string\">'b'<\/span>)) {\n            $borderOption = $request-&gt;query(<span class=\"hljs-string\">'b'<\/span>);\n\n            $imageUrl-&gt;border(Border::solid()-&gt;width(<span class=\"hljs-number\">3<\/span>)-&gt;color($borderOption));\n            $imageTag-&gt;border(Border::solid()-&gt;width(<span class=\"hljs-number\">3<\/span>)-&gt;color($borderOption));\n        }\n\n        <span class=\"hljs-keyword\">return<\/span> $imageTag-&gt;serialize();\n    }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p><strong>Result:<\/strong><\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/avatar_outline.png\" alt=\"Outline\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"445\"\/><\/p>\n<h2>Combination of Parameters<\/h2>\n<p>You can combine as many parameters as you desire\u2014in any order\u2014to retrieve the image associated with an account.<\/p>\n<p><strong>Example:<\/strong><\/p>\n<p>To retrieve a cartoonized, circular avatar of a 500&#215;500 size, optimized and in the best format, add the related parameters to the URL:<\/p>\n<p><code>http:\/\/localhost:8000\/avatar\/7b71271e3c93106dbc3b68fb867344e9?s=500&amp;d=hk&amp;rc=y&amp;f=auto&amp;q=auto<\/code><\/p>\n<p>Cloudinary returns this image:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/image\/upload\/w_700,c_fill,f_auto,q_auto\/Web_Assets\/blog\/avatar_q_f.png\" alt=\"avatar format and quality\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"700\" height=\"445\"\/><\/p>\n<p>Feel free to clone the <a href=\"https:\/\/github.com\/unicodeveloper\/clavatar\">Clavatar repository  on GitHub<\/a> and run the helpful service.<\/p>\n<h2>More Cloudinary Features<\/h2>\n<p>With Cloudinary, you can automate your entire image-management lifecycle, from <a href=\"https:\/\/cloudinary.com\/documentation\/image_transformations\">upload and transformation<\/a> to <a href=\"https:\/\/cloudinary.com\/documentation\/image_delivery_options\">optimization and delivery<\/a>. Notably, Cloudinary\u2019s <a href=\"https:\/\/cloudinary.com\/documentation\/upload_widget\">upload widget<\/a> offers a superfast way to upload multiple images in bulk. The platform also features numerous capabilities for <a href=\"https:\/\/cloudinary.com\/documentation\/video_manipulation_and_delivery\">editing and managing videos<\/a>.<\/p>\n<p>Do check them out.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":22262,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-22261","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-asset-management"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How to Build an Enhanced Gravatar Service, Part 2<\/title>\n<meta name=\"description\" content=\"Build an enhanced Gravatar service with options for various image versions associated with user accounts using Cloudinary&#039;s PHP Library.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Build an Enhanced Gravatar Service, Part 2\" \/>\n<meta property=\"og:description\" content=\"Build an enhanced Gravatar service with options for various image versions associated with user accounts using Cloudinary&#039;s PHP Library.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-06T17:40:49+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719608\/Web_Assets\/blog\/Cld_Blog_Img_Gravitars_2_222625d792\/Cld_Blog_Img_Gravitars_2_222625d792.png?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1540\" \/>\n\t<meta property=\"og:image:height\" content=\"847\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"How to Build an Enhanced Gravatar Service, Part 2\",\"datePublished\":\"2021-01-06T17:40:49+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2\"},\"wordCount\":8,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719608\/Web_Assets\/blog\/Cld_Blog_Img_Gravitars_2_222625d792\/Cld_Blog_Img_Gravitars_2_222625d792.png?_i=AA\",\"keywords\":[\"Asset Management\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2021\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2\",\"url\":\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2\",\"name\":\"How to Build an Enhanced Gravatar Service, Part 2\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719608\/Web_Assets\/blog\/Cld_Blog_Img_Gravitars_2_222625d792\/Cld_Blog_Img_Gravitars_2_222625d792.png?_i=AA\",\"datePublished\":\"2021-01-06T17:40:49+00:00\",\"description\":\"Build an enhanced Gravatar service with options for various image versions associated with user accounts using Cloudinary's PHP Library.\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719608\/Web_Assets\/blog\/Cld_Blog_Img_Gravitars_2_222625d792\/Cld_Blog_Img_Gravitars_2_222625d792.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719608\/Web_Assets\/blog\/Cld_Blog_Img_Gravitars_2_222625d792\/Cld_Blog_Img_Gravitars_2_222625d792.png?_i=AA\",\"width\":1540,\"height\":847},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Build an Enhanced Gravatar Service, Part 2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How to Build an Enhanced Gravatar Service, Part 2","description":"Build an enhanced Gravatar service with options for various image versions associated with user accounts using Cloudinary's PHP Library.","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:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2","og_locale":"en_US","og_type":"article","og_title":"How to Build an Enhanced Gravatar Service, Part 2","og_description":"Build an enhanced Gravatar service with options for various image versions associated with user accounts using Cloudinary's PHP Library.","og_url":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2","og_site_name":"Cloudinary Blog","article_published_time":"2021-01-06T17:40:49+00:00","og_image":[{"width":1540,"height":847,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719608\/Web_Assets\/blog\/Cld_Blog_Img_Gravitars_2_222625d792\/Cld_Blog_Img_Gravitars_2_222625d792.png?_i=AA","type":"image\/png"}],"twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2"},"author":{"name":"","@id":""},"headline":"How to Build an Enhanced Gravatar Service, Part 2","datePublished":"2021-01-06T17:40:49+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2"},"wordCount":8,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719608\/Web_Assets\/blog\/Cld_Blog_Img_Gravitars_2_222625d792\/Cld_Blog_Img_Gravitars_2_222625d792.png?_i=AA","keywords":["Asset Management"],"inLanguage":"en-US","copyrightYear":"2021","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2","url":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2","name":"How to Build an Enhanced Gravatar Service, Part 2","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719608\/Web_Assets\/blog\/Cld_Blog_Img_Gravitars_2_222625d792\/Cld_Blog_Img_Gravitars_2_222625d792.png?_i=AA","datePublished":"2021-01-06T17:40:49+00:00","description":"Build an enhanced Gravatar service with options for various image versions associated with user accounts using Cloudinary's PHP Library.","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719608\/Web_Assets\/blog\/Cld_Blog_Img_Gravitars_2_222625d792\/Cld_Blog_Img_Gravitars_2_222625d792.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719608\/Web_Assets\/blog\/Cld_Blog_Img_Gravitars_2_222625d792\/Cld_Blog_Img_Gravitars_2_222625d792.png?_i=AA","width":1540,"height":847},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/how_to_build_an_enhanced_gravatar_service_part_2#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to Build an Enhanced Gravatar Service, Part 2"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649719608\/Web_Assets\/blog\/Cld_Blog_Img_Gravitars_2_222625d792\/Cld_Blog_Img_Gravitars_2_222625d792.png?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22261","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=22261"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/22261\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/22262"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=22261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=22261"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=22261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}