<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet href="/atom.xsl" type="text/xsl"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:webfeeds="http://webfeeds.org/rss/1.0"><generator uri="https://gohugo.io">Hugo 0.155.0</generator><id>urn:uuid:43c22089-5c06-4cc4-8fd2-5b3563d5d257</id><link rel="self" type="application/atom+xml" href="https://fundor333.com/post/atom.xml" hreflang="en"/><link rel="alternate" type="text/html" href="https://fundor333.com/post/" hreflang="en"/><link rel="alternate" type="application/rss+xml" href="https://fundor333.com/post/index.xml" hreflang="en"/><link rel="alternate" type="application/json" href="https://fundor333.com/post/index.json" hreflang="en"/><icon>https://fundor333.com/apple-touch-icon.png</icon><logo>https://fundor333.com/img/logo.png</logo><subtitle>Fundor 333's personal space on the web</subtitle><title>Fundor333</title><updated>2026-03-10T19:47:42+01:00</updated><webfeeds:icon>https://fundor333.com/favicon-96x96.png</webfeeds:icon><entry><id>tag:fundor333.com,2026:/post/2026/why-do-i-disinstall-poetry-and-use-only-uv-/</id><link rel="alternate" href="https://fundor333.com/post/2026/why-do-i-disinstall-poetry-and-use-only-uv-/"/><title>Why Do I Disinstall Poetry and Use Only Uv</title><published>2026-01-26T21:58:02+01:00</published><updated>2026-03-08T23:58:29+00:00</updated><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>558 days ago (yes I count them), I wrote a follow-up article called <a class="a-post interlink-script" href="/post/2024/why-do-i-disinstall-pipenv-and-use-only-poetry/"  >Why Do I Disinstall Pipenv and Use Only Poetry?</a>
 and now I remake mine dev space, for building python project.</p>
<p>Some of the arguments are old, some are new but all come from my dev stack.</p>
<h2 id="build-a-venv" class="no-underline ">
  <a href="#build-a-venv">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Build a .venv
  </a>
  </h2>
<p>For every Python project I wrote, I code all the project with a Virtual Env or .venv.
It is a local &ldquo;installation&rdquo; of Python for the folder and it keep all the dependency inside it.</p>
<p>It is the best way to develop python project because you can have any number of Python project, with different version of Python and/or different version of the dipendency for each project.</p>
<p>Because I use git I need a good way to lock and commit the dipendency of my project. Some time ago I was using Poetry but now I use UV for build, update and manage the Virtual Env</p>
<p><img  class="center-img u-photo "  src="virtual-environment-make.jpg" alt="virtual-environment-make.jpg"></p>
<h2 id="creating-a-env-file" class="no-underline ">
  <a href="#creating-a-env-file">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Creating a .env file
  </a>
  </h2>
<p>Every python project I create, I always add a .env file, where I store all the environment variable for the project but I don&rsquo;t add them to the repo because It is not necessary add the local config for dev in a repo.</p>
<p>You can also automatically use the .env file in Uv so every time you are inside the .venv, you also have all the variables.</p>
<h2 id="using-uv" class="no-underline ">
  <a href="#using-uv">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Using UV
  </a>
  </h2>
<p>So after some time I was using Poetry and Pipenv, I find <a class="a-post interlink-script" href="https://github.com/astral-sh/uv"   target="_blank">UV&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
, a tool write in Rust for locking dipendnecy, set up and manage the .venv and create package for the publication in one tool.</p>
<p>You can easly start a procjet with a simple command</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>uv init</span></span></code></pre></div>
<p>which create the pyproject.toml and the .venv with all the dipendency.</p>
<p>With some other command you can easily add, remove and update the dipendency or import in a easy way your .env file.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>uv run --env-file<span style="color:#f92672">=</span>.env</span></span></code></pre></div>
<p>I move to UV because I can use a single tool for all my python necessity and it is faster and less bugged.</p>
<h2 id="editor-config" class="no-underline ">
  <a href="#editor-config">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Editor Config
  </a>
  </h2>
<p>We have the .venv, we have the .env, we have the dependency manager so I add the Editor Config file for the style of the code.
The <a class="a-post interlink-script" href="https://editorconfig.org/"   target="_blank">Editor Config file&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 is a file where you define the style for the type of file you write in your repo.</p>
<p>I have mine made year after year but I start with the <a class="a-post interlink-script" href="https://editorconfig.org/#example-file"   target="_blank">example&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 in the site because it is easy and with all the stuff you need.</p>
<h2 id="makefile-it" class="no-underline ">
  <a href="#makefile-it">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Makefile it
  </a>
  </h2>
<p>So, after adding stuff over stuff to the repo, I add a makefile where yu have all the aliases for a python project, <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>.</p>
<p>My basic makefile is something like this</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-Makefile" data-lang="Makefile"><span style="display:flex;"><span>SHELL <span style="color:#f92672">:=</span> /bin/bash
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>RUNNER <span style="color:#f92672">:=</span> uv run --env-file<span style="color:#f92672">=</span>.env
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">.PHONY</span><span style="color:#f92672">:</span> help
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">help</span><span style="color:#f92672">:</span> <span style="color:#75715e">## Show this help
</span></span></span><span style="display:flex;"><span>	@egrep -h <span style="color:#e6db74">&#39;\s##\s&#39;</span> <span style="color:#66d9ef">$(</span>MAKEFILE_LIST<span style="color:#66d9ef">)</span> | sort | awk <span style="color:#e6db74">&#39;BEGIN {FS = &#34;:.*?## &#34;}; {printf &#34;\033[36m%-20s\033[0m %s\n&#34;, $$1, $$2}&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">.PHONY</span><span style="color:#f92672">:</span> install
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">install</span><span style="color:#f92672">:</span> <span style="color:#75715e">## Make venv and install requirements
</span></span></span><span style="display:flex;"><span>	@uv sync
</span></span><span style="display:flex;"><span>	@<span style="color:#66d9ef">$(</span>RUNNER<span style="color:#66d9ef">)</span> pre-commit install
</span></span><span style="display:flex;"><span>	@pre-commit autoupdate
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">.PHONY</span><span style="color:#f92672">:</span> update
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">update</span><span style="color:#f92672">:</span> <span style="color:#75715e">## Update requirements
</span></span></span><span style="display:flex;"><span>	@uv lock --upgrade
</span></span><span style="display:flex;"><span>	@<span style="color:#66d9ef">$(</span>RUNNER<span style="color:#66d9ef">)</span> pre-commit autoupdate
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">precommit</span><span style="color:#f92672">:</span> <span style="color:#75715e">## Run pre-commit hooks
</span></span></span><span style="display:flex;"><span>	@git add . &amp; uv run --env-file<span style="color:#f92672">=</span>.env pre-commit run --all-files
</span></span></code></pre></div>
<p>The help command come form a blog post<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> and describe better at my other post<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></p>
<p>I write a makefile for all my project because I forgot a lot of the command and parameters, so a makefile is a good way to have an &ldquo;deploy&rdquo; command or a &ldquo;test&rdquo; command for the project and forgot all the task needed for run a &ldquo;test&rdquo; or a &ldquo;deploy&rdquo;.</p>
<p>I also put all the test command into the makefile because sometime the test command is too long to remember&hellip;</p>
<h2 id="pre-commit-and-some-automation" class="no-underline ">
  <a href="#pre-commit-and-some-automation">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Pre commit and some automation
  </a>
  </h2>
<p>This is my personal safety net for the commits. Some time I wrote and push without any work or thing about what I am doing&hellip; For this reason I add pre-commit<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup> for autofix and check all this minor error.</p>
<p><img  class="center-img u-photo "  src="cox.gif" alt="cox.gif"></p>
<p>The took launch a lot of test BEFORE I can save the commit so I can find the error or getting a big fat NOPE for the commit, which I need to review for the problem.</p>
<h2 id="conclusion" class="no-underline ">
  <a href="#conclusion">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Conclusion
  </a>
  </h2>
<p>This is the stack I work with and I love it. It can be something custom and old style for some of the older tecnology but I find it complete for what I do.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>I wrote an article about makefile caller <a class="a-post interlink-script" href="https://fundor333.com/post/2021/the-team-makefile/"   target="_blank">The Team Makefile&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p><a class="a-post interlink-script" href="https://victoria.dev/archive/how-to-create-a-self-documenting-makefile/"   target="_blank">How to create a self-documenting Makefile&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p><a class="a-post interlink-script" href="https://fundor333.com/post/2021/the-team-makefile/"   target="_blank">The Team Makefile&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p><a class="a-post interlink-script" href="https://praful932.dev/blog-2-pre-commit-hooks/"   target="_blank">Using pre-commit hooks to write better code&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content></entry><entry><id>tag:fundor333.com,2026:/post/2026/htmx-django-and-django-table2/</id><link rel="alternate" href="https://fundor333.com/post/2026/htmx-django-and-django-table2/"/><title>Htmx Django and Django Table2</title><published>2026-01-19T12:33:09+01:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">How I use Htmx for showing in a Django project a django-table2 filled with data from a MonthArchiveView</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>For some time I am developing my personal Django server. It keeps some data for me and it is my automation server. And I want to test a Htmx code on Django so I make a little thing in my personal django project.</p>
<h2 id="what-i-have" class="no-underline ">
  <a href="#what-i-have">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    What I have
  </a>
  </h2>
<p>I have a MonthArchiveView with render a table list with a lot of function I need: add element, change month show, exports query as files, etc&hellip;</p>
<p>I also don&rsquo;t like to reload all the page for change the month I am seeing on the page.
So I start to implement what I need.</p>
<p>And, from some comment from the web and some friends, I want less code and more clean one.</p>
<h2 id="what-i-used" class="no-underline ">
  <a href="#what-i-used">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    What I used
  </a>
  </h2>
<p>For this project I used:</p>
<ul>
<li><strong>Django</strong> the framework used<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></li>
<li><strong>Django Table2</strong> a module for easy creation of table for Django<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></li>
<li><strong>Django Htmx</strong> a module for easy support of Htmx<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></li>
<li><strong>Tablib</strong> a module for exporting the table as multiple file type<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup></li>
</ul>
<h3 id="the-py-code" class="no-underline ">
  <a href="#the-py-code">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The Py code
  </a>
  </h3>
<p>So I start with the code for the model. It need to have a DateTimeField or a DateField (this becose I want to have an MonthArchiveView view).</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># blog/model.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Post</span>(models<span style="color:#f92672">.</span>Model):
</span></span><span style="display:flex;"><span>    title <span style="color:#f92672">=</span> models<span style="color:#f92672">.</span>CharField(max_length<span style="color:#f92672">=</span><span style="color:#ae81ff">400</span>)
</span></span><span style="display:flex;"><span>    slug <span style="color:#f92672">=</span> models<span style="color:#f92672">.</span>SlugField(max_length<span style="color:#f92672">=</span><span style="color:#ae81ff">400</span>, unique<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>, blank<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)
</span></span><span style="display:flex;"><span>    content <span style="color:#f92672">=</span> models<span style="color:#f92672">.</span>TextAreaField()
</span></span><span style="display:flex;"><span>    date <span style="color:#f92672">=</span> models<span style="color:#f92672">.</span>DateTimeField(auto_now_add<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)</span></span></code></pre></div><p>and after I add the code for the table with the ordering of the data</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># blog/tables.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> django_tables2 <span style="color:#66d9ef">as</span> tables
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> blog.models <span style="color:#f92672">import</span> Post
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">PostTable</span>(tables<span style="color:#f92672">.</span>Table):
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Meta</span>:
</span></span><span style="display:flex;"><span>        model <span style="color:#f92672">=</span> Post
</span></span><span style="display:flex;"><span>        order_by <span style="color:#f92672">=</span> (<span style="color:#e6db74">&#34;-date&#34;</span>, <span style="color:#e6db74">&#34;title&#34;</span>)
</span></span><span style="display:flex;"><span>        fields <span style="color:#f92672">=</span> [<span style="color:#e6db74">&#34;date&#34;</span>, <span style="color:#e6db74">&#34;title&#34;</span>, <span style="color:#e6db74">&#34;slug&#34;</span>]</span></span></code></pre></div><p>After the model and the table we need the view called by the HTMX code.</p>
<p>I set all the config for choose the right data field and which is the format for month and year, followed for the export types&rsquo; settings.</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># blog/views.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> django.views.generic <span style="color:#f92672">import</span> ListView
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> django.contrib.auth.mixins <span style="color:#f92672">import</span> LoginRequiredMixin
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> django_tables2 <span style="color:#f92672">import</span> SingleTableView, tables
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> blog.models <span style="color:#f92672">import</span> Post
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> blog.tables <span style="color:#f92672">import</span> PostTable
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">PostMonthArchiveHtmx</span>(LoginRequiredMixin, ExportMixin, SingleTableMixin, MonthArchiveView):
</span></span><span style="display:flex;"><span>    model <span style="color:#f92672">=</span> Post
</span></span><span style="display:flex;"><span>    template_name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;generic/table2_with_export.html&#34;</span>
</span></span><span style="display:flex;"><span>    table_class <span style="color:#f92672">=</span> PostTable
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    date_field <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;date&#34;</span>
</span></span><span style="display:flex;"><span>    allow_future <span style="color:#f92672">=</span> <span style="color:#66d9ef">True</span>
</span></span><span style="display:flex;"><span>    month_format <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;%m&#34;</span>
</span></span><span style="display:flex;"><span>    year_format <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;%Y&#34;</span>
</span></span><span style="display:flex;"><span>    allow_empty <span style="color:#f92672">=</span> <span style="color:#66d9ef">True</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    export_formats <span style="color:#f92672">=</span> (
</span></span><span style="display:flex;"><span>    TableExport<span style="color:#f92672">.</span>CSV,
</span></span><span style="display:flex;"><span>    TableExport<span style="color:#f92672">.</span>XLS,
</span></span><span style="display:flex;"><span>    TableExport<span style="color:#f92672">.</span>XLSX,
</span></span><span style="display:flex;"><span>    TableExport<span style="color:#f92672">.</span>ODS,)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">get_month</span>(self):
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span>            month <span style="color:#f92672">=</span> super()<span style="color:#f92672">.</span>get_month()
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">except</span> Http404:
</span></span><span style="display:flex;"><span>            month <span style="color:#f92672">=</span> now()<span style="color:#f92672">.</span>strftime(self<span style="color:#f92672">.</span>get_month_format())
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> month
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">get_year</span>(self):
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span>            year <span style="color:#f92672">=</span> super()<span style="color:#f92672">.</span>get_year()
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">except</span> Http404:
</span></span><span style="display:flex;"><span>            year <span style="color:#f92672">=</span> now()<span style="color:#f92672">.</span>strftime(self<span style="color:#f92672">.</span>get_year_format())
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> year
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">get_export_filename</span>(self, export_format):
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Export Post </span><span style="color:#e6db74">{</span>self<span style="color:#f92672">.</span>get_year()<span style="color:#e6db74">}</span><span style="color:#e6db74">-</span><span style="color:#e6db74">{</span>self<span style="color:#f92672">.</span>get_month()<span style="color:#e6db74">}</span><span style="color:#e6db74">.</span><span style="color:#e6db74">{</span>export_format<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span></span></span></code></pre></div><p>I added a function for changing the name of the output file (because I like filename with date reference) and two functions for setting month and year if not given (we need them later for the Htmx part).</p>
<h3 id="the-jinja-part" class="no-underline ">
  <a href="#the-jinja-part">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The Jinja part
  </a>
  </h3>
<p>After the python code I wrote this generic template for all my django-table2 table (in this case with the export code)</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-django" data-lang="django"><span style="display:flex;"><span># templates/generic/table2_with_export.html
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{%</span> <span style="color:#66d9ef">load</span> render_table from django_tables2 <span style="color:#75715e">%}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{%</span> <span style="color:#66d9ef">load</span> export_url from django_tables2 <span style="color:#75715e">%}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;div&gt;
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">{%</span> <span style="color:#66d9ef">for</span> format <span style="color:#66d9ef">in</span> view.export_formats <span style="color:#75715e">%}</span>
</span></span><span style="display:flex;"><span>    &lt;a href=&#34;<span style="color:#75715e">{{</span> request.path <span style="color:#75715e">}}{%</span> <span style="color:#66d9ef">export_url</span> format <span style="color:#75715e">%}</span>&#34; target=&#34;_blank&#34;&gt;
</span></span><span style="display:flex;"><span>      &lt;code&gt;<span style="color:#75715e">{{</span> format <span style="color:#75715e">}}</span>&lt;/code&gt;
</span></span><span style="display:flex;"><span>    &lt;/a&gt;
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">{%</span> <span style="color:#66d9ef">endfor</span> <span style="color:#75715e">%}</span>
</span></span><span style="display:flex;"><span>    &lt;hr&gt;
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">{%</span> <span style="color:#66d9ef">render_table</span> table <span style="color:#75715e">%}</span>
</span></span><span style="display:flex;"><span>&lt;/div&gt;</span></span></code></pre></div><p>I take out all the css stuff so you can add your style and/or css classes.</p>
<p>At this point we have all we need to have a html page with the table and the exports we need. We only need to add this view into the urls&hellip;</p>
<p>For example this is a generic example for a urls file for this project</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#75715e"># blog/urls.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> django.urls <span style="color:#f92672">import</span> path
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> blog.views <span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>    PostMonthArchiveHtmx,
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>app_name <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;blog&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>urlpatterns <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    path(<span style="color:#e6db74">&#34;htmx/post&#34;</span>, PostMonthArchiveHtmx<span style="color:#f92672">.</span>as_view(month_format<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;%m&#34;</span>,name<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;htmx-post&#34;</span>)),
</span></span><span style="display:flex;"><span>]</span></span></code></pre></div><p>You can see that I didn&rsquo;t add the code for having the month and the year in the url. This is because I had a lot of problems with the next part and this is the cleanest way I found to code this.</p>
<h3 id="the-htmx-fragment" class="no-underline ">
  <a href="#the-htmx-fragment">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The Htmx fragment
  </a>
  </h3>
<p>I will assume that you have done the quickstart form Htmx&rsquo;s site<sup id="fnref:5"><a href="#fn:5" class="footnote-ref" role="doc-noteref">5</a></sup> because I don&rsquo;t want to write about Htmx&hellip;</p>
<p>So for using inside a Django project for calling the page with Htmx we need to add the csrf token inside the header of the request so I added inside the main tag for my project.</p>
<p>It resembles this fragment.</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span><span style="color:#75715e">&lt;!-- template/base.html --&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">&lt;!-- Other part of the template--&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">div</span> <span style="color:#a6e22e">hx-headers</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#39;{&#34;x-csrftoken&#34;: &#34;{{ csrf_token }}&#34;}&#39;</span>&gt;
</span></span><span style="display:flex;"><span>  {% block content %}
</span></span><span style="display:flex;"><span>    (no content)
</span></span><span style="display:flex;"><span>  {% endblock %}
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">&lt;!-- Other part of the template--&gt;</span></span></span></code></pre></div><p>So now I need to write the div for the Htmx. And this is what I wrote:</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-html" data-lang="html"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">div</span> <span style="color:#a6e22e">hx-get</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;{% url &#39;blog:htmx-post&#39; %}?year={{ month|date:&#34;</span><span style="color:#a6e22e">Y</span><span style="color:#960050;background-color:#1e0010">&#34;</span> <span style="color:#960050;background-color:#1e0010">}}&amp;</span><span style="color:#a6e22e">month</span><span style="color:#f92672">=</span><span style="color:#e6db74">{{</span> <span style="color:#a6e22e">month</span><span style="color:#960050;background-color:#1e0010">|</span><span style="color:#a6e22e">date:</span><span style="color:#960050;background-color:#1e0010">&#34;</span><span style="color:#a6e22e">m</span><span style="color:#960050;background-color:#1e0010">&#34;</span> <span style="color:#960050;background-color:#1e0010">}}&amp;{{</span> <span style="color:#a6e22e">request</span><span style="color:#960050;background-color:#1e0010">.</span><span style="color:#a6e22e">GET</span><span style="color:#960050;background-color:#1e0010">.</span><span style="color:#a6e22e">urlencode</span> <span style="color:#960050;background-color:#1e0010">}}&#34;</span>
</span></span><span style="display:flex;"><span>     <span style="color:#a6e22e">hx-trigger</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;load&#34;</span>&gt;This will be replaced.&lt;/<span style="color:#f92672">div</span>&gt;</span></span></code></pre></div><p>I build the url in the hx-get in a strange way because I need to add the query input for the MonthArchiveView (the &amp;month and &amp;year field in the url) and add all the other field. In this way I also have the sorting links in the header of the table working.</p>
<h2 id="conclusion" class="no-underline ">
  <a href="#conclusion">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Conclusion
  </a>
  </h2>
<p>This is how I have combine this 3 libs for my personal project and if you find it useful share it. Thanks!</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a class="a-post interlink-script" href="https://www.djangoproject.com/"   target="_blank">Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of web development, so you can focus on writing your app without needing to reinvent the wheel. It’s free and open source&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p><a class="a-post interlink-script" href="https://github.com/jieter/django-tables2"   target="_blank">django-tables2 - An app for creating HTML tables&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p><a class="a-post interlink-script" href="https://pypi.org/project/django-htmx/"   target="_blank">django-htmx Extensions for using Django with htmx&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p><a class="a-post interlink-script" href="https://pypi.org/project/tablib/"   target="_blank">Tablib: format-agnostic tabular dataset library&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:5">
<p><a class="a-post interlink-script" href="https://htmx.org/docs/#introduction"   target="_blank">htmx in a Nutshell&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:5" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/generate-dataframe-summaries-with-python/</id><link rel="alternate" href="https://fundor333.com/post/2025/generate-dataframe-summaries-with-python/"/><title>Generate Dataframe Summaries With Python</title><published>2025-09-03T17:13:02+08:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">How to generate dataframe summaries with python and AI for a type of dataset</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>How much time do you spend with making summaries of dataset? Too much and I don&rsquo;t like doing it so I search to do it with the AI. So this is my sperimentation with some medical data see at PyDataVe 22nd event and Mistral model.</p>
<h2 id="the-code-for-the-inizializzation" class="no-underline ">
  <a href="#the-code-for-the-inizializzation">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The code for the inizializzation
  </a>
  </h2>
<p>For start I need to install some dipendency</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>langchain&gt;=0.3.27
</span></span><span style="display:flex;"><span>langchain-ollama&gt;=0.3.7
</span></span><span style="display:flex;"><span>pandas&gt;=2.3.2</span></span></code></pre></div>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> pandas <span style="color:#66d9ef">as</span> pd
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> langchain_ollama <span style="color:#f92672">import</span> ChatOllama
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> typing <span style="color:#f92672">import</span> Literal
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>df <span style="color:#f92672">=</span> pd<span style="color:#f92672">.</span>read_csv(<span style="color:#e6db74">&#34;data/test.csv&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>print(<span style="color:#e6db74">&#34;-*-&#34;</span> <span style="color:#f92672">*</span> <span style="color:#ae81ff">20</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;Dataset shape: </span><span style="color:#e6db74">{</span>df<span style="color:#f92672">.</span>shape<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#e6db74">&#34;-*-&#34;</span> <span style="color:#f92672">*</span> <span style="color:#ae81ff">20</span>)
</span></span><span style="display:flex;"><span>print(<span style="color:#e6db74">&#34;Missing value stats:&#34;</span>)
</span></span><span style="display:flex;"><span>print(df<span style="color:#f92672">.</span>isnull()<span style="color:#f92672">.</span>sum())</span></span></code></pre></div><pre><code>-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
Dataset shape: (418, 20)
-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-
Missing value stats:
ID                 0
N_Days             0
Status             0
Drug             106
Age                0
Sex                0
Ascites          106
Hepatomegaly     106
Spiders          106
Edema              0
Bilirubin          0
Cholesterol      134
Albumin            0
Copper           108
Alk_Phos         106
SGOT             106
Tryglicerides    136
Platelets         11
Prothrombin        2
Stage              6
dtype: int64
</code></pre>
<p>This is a section of the dataset and what is missing value of the stats.</p>
<p>Now we will start with the AI. In my case I user Ollama with Mistral model.
I install the model with</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ollama run mistral</span></span></code></pre></div><p>And prepare the code for use the model. First you need to make a connection with the local LLM instance. This code use Mistral but you can pass any local LLM instance you have.</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">get_llm</span>(model_name: str <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;mistral:latest&#34;</span>) <span style="color:#f92672">-&gt;</span> ChatOllama:
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Create and configure a ChatOllama instance for local LLM inference.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    This function initializes a ChatOllama client configured to connect to a
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    local Ollama server. The client is set up with deterministic output
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    (temperature=0) for consistent responses across multiple calls with the
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    same input.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Parameters
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    ----------
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    model_name : str, optional
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        The name of the Ollama model to use for chat completions.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        Must be a valid model name that is available on the local Ollama
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        installation. Default is &#34;mistral:latest&#34;.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    Returns
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    -------
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    ChatOllama
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        A configured ChatOllama instance ready for chat completions.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> ChatOllama(
</span></span><span style="display:flex;"><span>        model<span style="color:#f92672">=</span>model_name, base_url<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;http://localhost:11434&#34;</span>, temperature<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>    )</span></span></code></pre></div><p>If you want to test the connection you can use this command</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>print(get_llm()<span style="color:#f92672">.</span>invoke(<span style="color:#e6db74">&#34;test&#34;</span>)<span style="color:#f92672">.</span>content)</span></span></code></pre></div><pre><code> Hallo! Wie geht es Ihnen? Ich bin hier, um Ihnen zu helfen. Was möchten Sie heute tun?

Ich kann Ihnen beispielsweise helfen:

* Fragen beantworten
* Informationen suchen
* Aufgaben lösen
* und vieles mehr!

Welche Aufgabe haben wir heute vor uns?
</code></pre>
<h2 id="make-a-context" class="no-underline ">
  <a href="#make-a-context">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Make a context
  </a>
  </h2>
<p>Now we need to generate a context for the LLM. If you do this function with all the necessary data you can relaunch this script every time you need a new README/summary of the dataset. This is better to be a dataset with a fixed schema and a date which change every year like medical data (this), monthly sell report, census data&hellip;</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">get_summary_context_message</span>(df: pd<span style="color:#f92672">.</span>DataFrame, dataset_name:str) <span style="color:#f92672">-&gt;</span> str:
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Basic application statistics</span>
</span></span><span style="display:flex;"><span>    total_analisys <span style="color:#f92672">=</span> len(df)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Gender distribution</span>
</span></span><span style="display:flex;"><span>    gender_counts <span style="color:#f92672">=</span> df[<span style="color:#e6db74">&#34;Sex&#34;</span>]<span style="color:#f92672">.</span>value_counts()
</span></span><span style="display:flex;"><span>    male_count <span style="color:#f92672">=</span> gender_counts<span style="color:#f92672">.</span>get(<span style="color:#e6db74">&#34;M&#34;</span>, <span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>    female_count <span style="color:#f92672">=</span> gender_counts<span style="color:#f92672">.</span>get(<span style="color:#e6db74">&#34;F&#34;</span>, <span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># Stage Statistics</span>
</span></span><span style="display:flex;"><span>    stage_data <span style="color:#f92672">=</span> df[<span style="color:#e6db74">&#34;Stage&#34;</span>]<span style="color:#f92672">.</span>dropna()
</span></span><span style="display:flex;"><span>    stage_avg <span style="color:#f92672">=</span> stage_data<span style="color:#f92672">.</span>mean()
</span></span><span style="display:flex;"><span>    stage_25th <span style="color:#f92672">=</span> stage_data<span style="color:#f92672">.</span>quantile(<span style="color:#ae81ff">0.25</span>)
</span></span><span style="display:flex;"><span>    stage_50th <span style="color:#f92672">=</span> stage_data<span style="color:#f92672">.</span>quantile(<span style="color:#ae81ff">0.50</span>)
</span></span><span style="display:flex;"><span>    stage_75th <span style="color:#f92672">=</span> stage_data<span style="color:#f92672">.</span>quantile(<span style="color:#ae81ff">0.75</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e"># NDays Statistics</span>
</span></span><span style="display:flex;"><span>    days_data <span style="color:#f92672">=</span> df[<span style="color:#e6db74">&#34;N_Days&#34;</span>]<span style="color:#f92672">.</span>dropna()
</span></span><span style="display:flex;"><span>    days_avg <span style="color:#f92672">=</span> days_data<span style="color:#f92672">.</span>mean()
</span></span><span style="display:flex;"><span>    days_25th <span style="color:#f92672">=</span> days_data<span style="color:#f92672">.</span>quantile(<span style="color:#ae81ff">0.25</span>)
</span></span><span style="display:flex;"><span>    days_50th <span style="color:#f92672">=</span> days_data<span style="color:#f92672">.</span>quantile(<span style="color:#ae81ff">0.50</span>)
</span></span><span style="display:flex;"><span>    days_75th <span style="color:#f92672">=</span> days_data<span style="color:#f92672">.</span>quantile(<span style="color:#ae81ff">0.75</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">status_category</span>(exp):
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> pd<span style="color:#f92672">.</span>isna(exp):
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;Unkown&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">elif</span> exp <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;C&#34;</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;Censored&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">elif</span> exp <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;CL&#34;</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;Censored due to Lever tx&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">elif</span> exp <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;D&#34;</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;Death&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;Unkow&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    df[<span style="color:#e6db74">&#39;Status Str&#39;</span>]<span style="color:#f92672">=</span> df[<span style="color:#e6db74">&#39;Status&#39;</span>]<span style="color:#f92672">.</span>apply(status_category)
</span></span><span style="display:flex;"><span>    status_str_stats <span style="color:#f92672">=</span> []
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> category <span style="color:#f92672">in</span> [<span style="color:#e6db74">&#34;Censored&#34;</span>, <span style="color:#e6db74">&#34;Censored due to Lever tx&#34;</span>, <span style="color:#e6db74">&#34;Death&#34;</span>,]:
</span></span><span style="display:flex;"><span>        category_data <span style="color:#f92672">=</span> df[df[<span style="color:#e6db74">&#34;Status Str&#34;</span>] <span style="color:#f92672">==</span> category]
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> len(category_data) <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">0</span>:
</span></span><span style="display:flex;"><span>            male <span style="color:#f92672">=</span> len(category_data[category_data[<span style="color:#e6db74">&#34;Sex&#34;</span>] <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;M&#34;</span>])
</span></span><span style="display:flex;"><span>            female <span style="color:#f92672">=</span> len(category_data[category_data[<span style="color:#e6db74">&#34;Sex&#34;</span>] <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;F&#34;</span>])
</span></span><span style="display:flex;"><span>            total <span style="color:#f92672">=</span> len(category_data)
</span></span><span style="display:flex;"><span>            rate_m <span style="color:#f92672">=</span> (male <span style="color:#f92672">/</span> total) <span style="color:#f92672">*</span> <span style="color:#ae81ff">100</span>
</span></span><span style="display:flex;"><span>            rate_f <span style="color:#f92672">=</span> (female <span style="color:#f92672">/</span> total) <span style="color:#f92672">*</span> <span style="color:#ae81ff">100</span>
</span></span><span style="display:flex;"><span>            status_str_stats<span style="color:#f92672">.</span>append((category, male, female, total, rate_m, rate_f))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    summary <span style="color:#f92672">=</span><span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;&#34;&#34;</span><span style="color:#e6db74">{</span>dataset_name<span style="color:#e6db74">}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Total Analisys: </span><span style="color:#e6db74">{</span>total_analisys<span style="color:#e6db74">:</span><span style="color:#e6db74">,</span><span style="color:#e6db74">}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Gender Distribution:
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">- Male applicants: </span><span style="color:#e6db74">{</span>male_count<span style="color:#e6db74">:</span><span style="color:#e6db74">,</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> (</span><span style="color:#e6db74">{</span>male_count<span style="color:#f92672">/</span>total_analisys<span style="color:#f92672">*</span><span style="color:#ae81ff">100</span><span style="color:#e6db74">:</span><span style="color:#e6db74">.1f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">%)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">- Female applicants: </span><span style="color:#e6db74">{</span>female_count<span style="color:#e6db74">:</span><span style="color:#e6db74">,</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> (</span><span style="color:#e6db74">{</span>female_count<span style="color:#f92672">/</span>total_analisys<span style="color:#f92672">*</span><span style="color:#ae81ff">100</span><span style="color:#e6db74">:</span><span style="color:#e6db74">.1f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">%)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Stage Statistics:
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">- Average Stage: </span><span style="color:#e6db74">{</span>stage_avg<span style="color:#e6db74">:</span><span style="color:#e6db74">.2f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">- 25th percentile: </span><span style="color:#e6db74">{</span>stage_25th<span style="color:#e6db74">:</span><span style="color:#e6db74">.2f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">- 50th percentile (median): </span><span style="color:#e6db74">{</span>stage_50th<span style="color:#e6db74">:</span><span style="color:#e6db74">.2f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">- 75th percentile: </span><span style="color:#e6db74">{</span>stage_75th<span style="color:#e6db74">:</span><span style="color:#e6db74">.2f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">N Day Statistics:
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">- N Days Stage: </span><span style="color:#e6db74">{</span>days_avg<span style="color:#e6db74">:</span><span style="color:#e6db74">.2f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">- 25th percentile: </span><span style="color:#e6db74">{</span>days_25th<span style="color:#e6db74">:</span><span style="color:#e6db74">.2f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">- 50th percentile (median): </span><span style="color:#e6db74">{</span>days_50th<span style="color:#e6db74">:</span><span style="color:#e6db74">.2f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">- 75th percentile: </span><span style="color:#e6db74">{</span>days_75th<span style="color:#e6db74">:</span><span style="color:#e6db74">.2f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    summary <span style="color:#f92672">+=</span> <span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n\n</span><span style="color:#e6db74">Status Rates by Sex:&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> category, male, female, total, rate_m, rate_f <span style="color:#f92672">in</span> status_str_stats:
</span></span><span style="display:flex;"><span>        summary <span style="color:#f92672">+=</span> (
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">- </span><span style="color:#e6db74">{</span>category<span style="color:#e6db74">}</span><span style="color:#e6db74">: </span><span style="color:#e6db74">{</span>male<span style="color:#e6db74">}</span><span style="color:#e6db74">/</span><span style="color:#e6db74">{</span>total<span style="color:#e6db74">}</span><span style="color:#e6db74"> Male (</span><span style="color:#e6db74">{</span>rate_m<span style="color:#e6db74">:</span><span style="color:#e6db74">.1f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">% rate)&#34;</span><span style="color:#f92672">+</span>
</span></span><span style="display:flex;"><span>            <span style="color:#e6db74">f</span><span style="color:#e6db74">&#34;</span><span style="color:#ae81ff">\n</span><span style="color:#e6db74">- </span><span style="color:#e6db74">{</span>category<span style="color:#e6db74">}</span><span style="color:#e6db74">: </span><span style="color:#e6db74">{</span>female<span style="color:#e6db74">}</span><span style="color:#e6db74">/</span><span style="color:#e6db74">{</span>total<span style="color:#e6db74">}</span><span style="color:#e6db74"> Female (</span><span style="color:#e6db74">{</span>rate_f<span style="color:#e6db74">:</span><span style="color:#e6db74">.1f</span><span style="color:#e6db74">}</span><span style="color:#e6db74">% rate)&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        )
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> summary</span></span></code></pre></div><h2 id="make-a-report" class="no-underline ">
  <a href="#make-a-report">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Make a report
  </a>
  </h2>
<p>After checking all you need to have a template for the repo of the dataset.</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>SUMMARIZE_DATAFRAME_PROMPT <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">You are an expert data analyst and data summarizer.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Your task is to take in complex datasets and return user-friendly descriptions and findings.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">You were given this dataset:
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">- Name: </span><span style="color:#e6db74">{dataset_name}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">- Source: </span><span style="color:#e6db74">{dataset_source}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">This dataset was analyzed in a pipeline before it was given to you.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">These are the findings returned by the analysis pipeline:
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&lt;context&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">{context}</span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&lt;/context&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Based on these findings, write a detailed report in </span><span style="color:#e6db74">{report_format}</span><span style="color:#e6db74"> format.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Give the report a meaningful title and separate findings into sections with headings and subheadings.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Output only the report in </span><span style="color:#e6db74">{report_format}</span><span style="color:#e6db74"> and nothing else.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Report:
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&#34;&#34;&#34;</span></span></span></code></pre></div><p>This prompt and a lot of the code of this article are from <a class="a-post interlink-script" href="https://towardsdatascience.com/llms-pandas-how-i-use-generative-ai-to-generate-pandas-dataframe-summaries-2/"   target="_blank">this post&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
.</p>
<p>After this we need a function that take the dataset <em>df</em>, the prompt <em>SUMMARIZE_DATAFRAME_PROMPT</em> with the needed info and return the content of the report.</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">get_report_summary</span>(
</span></span><span style="display:flex;"><span>    dataset: pd<span style="color:#f92672">.</span>DataFrame,
</span></span><span style="display:flex;"><span>    dataset_name: str,
</span></span><span style="display:flex;"><span>    dataset_source: str,
</span></span><span style="display:flex;"><span>    report_format: Literal[<span style="color:#e6db74">&#34;markdown&#34;</span>, <span style="color:#e6db74">&#34;html&#34;</span>] <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;markdown&#34;</span>,
</span></span><span style="display:flex;"><span>) <span style="color:#f92672">-&gt;</span> str:
</span></span><span style="display:flex;"><span>    context_message <span style="color:#f92672">=</span> get_summary_context_message(df<span style="color:#f92672">=</span>dataset, dataset_name<span style="color:#f92672">=</span>dataset_name)
</span></span><span style="display:flex;"><span>    prompt <span style="color:#f92672">=</span> SUMMARIZE_DATAFRAME_PROMPT<span style="color:#f92672">.</span>format(
</span></span><span style="display:flex;"><span>        dataset_name<span style="color:#f92672">=</span>dataset_name,
</span></span><span style="display:flex;"><span>        dataset_source<span style="color:#f92672">=</span>dataset_source,
</span></span><span style="display:flex;"><span>        context<span style="color:#f92672">=</span>context_message,
</span></span><span style="display:flex;"><span>        report_format<span style="color:#f92672">=</span>report_format,
</span></span><span style="display:flex;"><span>    )
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> get_llm()<span style="color:#f92672">.</span>invoke(input<span style="color:#f92672">=</span>prompt)<span style="color:#f92672">.</span>content</span></span></code></pre></div><p>In our case we launch it as</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>md_report <span style="color:#f92672">=</span> get_report_summary(
</span></span><span style="display:flex;"><span>    dataset<span style="color:#f92672">=</span>df,
</span></span><span style="display:flex;"><span>    dataset_name<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Cirrhosis Patient Survival Prediction&#34;</span>,
</span></span><span style="display:flex;"><span>    dataset_source<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://www.kaggle.com/datasets/joebeachcapital/cirrhosis-patient-survival-prediction/data&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>print(md_report)</span></span></code></pre></div><pre><code> # Cirrhosis Patient Survival Prediction Analysis Report

## Overview
The dataset analyzed consists of 418 records related to cirrhosis patients, sourced from [Kaggle](https://www.kaggle.com/datasets/joebeachcapital/cirrhosis-patient-survival-prediction/data). The data provides information about the patient's gender, stage of cirrhosis, number of days since diagnosis, and final status (censored or death).

## Demographics
### Gender Distribution
The dataset shows a significant imbalance in gender distribution with 89.5% female applicants (374) and only 10.5% male applicants (44).

## Cirrhosis Stage Statistics
### Average Stage
The average stage of cirrhosis for the analyzed patients is 3.02, indicating a severe level of liver damage.

### Percentiles
- **25th percentile**: The cirrhosis stage is at least 2.00 for 25% of the patients.
- **Median (50th percentile)**: Half of the patients have a cirrhosis stage of 3.00.
- **75th percentile**: For 75% of the patients, the cirrhosis stage is 4.00 or lower.

## N Days Statistics
### N Days Stage
The average number of days since diagnosis for the analyzed patients is 1917.78 days.

### Percentiles
- **25th percentile**: The minimum number of days since diagnosis for 25% of the patients is 1092.75 days.
- **Median (50th percentile)**: Half of the patients have been diagnosed with cirrhosis for at least 1730.00 days.
- **75th percentile**: For 75% of the patients, the number of days since diagnosis is 2613.50 days or less.

## Status Rates by Sex
The following table shows the rates of different statuses (censored due to Lever tx and death) for both male and female applicants:

|                     | Male Applicants | Female Applicants |
|---------------------|-----------------|-------------------|
| Censored            | 17/232 (7.3%)    | 215/232 (92.7%)   |
| Censored due to Lever tx | 3/25 (12.0%)     | 22/25 (88.0%)     |
| Death                | 24/161 (14.9%)   | 137/161 (85.1%)   |

The analysis indicates that female applicants are more likely to have their status censored, either due to the lack of information or other factors, while male applicants are more likely to experience death. However, it's important to note that the sample size for male applicants is significantly smaller than that of female applicants.
</code></pre>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/hugo-blog-with-jupyter-notebook/</id><link rel="alternate" href="https://fundor333.com/post/2025/hugo-blog-with-jupyter-notebook/"/><title>Hugo Blog With Jupyter Notebook</title><published>2025-09-01T08:40:34+02:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">How to integrate a Jupyter Notebook to your Hugo Blog</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>A long time ago, I wrote a <a class="a-post interlink-script" href="/post/2017/jupyter-notebook-pelican-combo/"  >post</a>
 about writing a post for the Pelican static site generator made with a Jupyter Notebook. I did it because, at the time, I was a huge fan of the Notebooks and I had the blog generated by Pelican so&hellip;</p>
<p><img  class="center-img u-photo "  src="pydatave.jpg" alt="pydatave.jpg"></p>
<p>And now, after a PyDataVe (the 22nd event), I make a Jupyter Notebook after a lot of time and I feel the need to have a solution for make a Jupyter Notebook one of the post of my blog so I find a way to do it. This time in Hugo</p>
<h2 id="jupyter-in-my-hugo" class="no-underline ">
  <a href="#jupyter-in-my-hugo">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Jupyter in my Hugo
  </a>
  </h2>
<p>So first I search for a way to convert a Jupyter Notebook to a Markdown file with the headers for Hugo. So I find a <a class="a-post interlink-script" href="https://github.com/soda92/hugo-nbconvert"   target="_blank">python module&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 to generate a Notebook with a starting metadata for my blog. All the metadata are inside the first cell set as a Markdown type cell.</p>
<p>All this is made by launching this command for generate the notebook</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>hugo_nbnew content/post/test-hugo-page</span></span></code></pre></div><p>And at the end of all the writing I launch this command</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>hugo_nbconvert content/post/test-hugo-page/index.ipynb</span></span></code></pre></div><p>for generate/updating the markdown file for Hugo.</p>
<h2 id="other-little-things-i-have-done" class="no-underline ">
  <a href="#other-little-things-i-have-done">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Other little things I have done
  </a>
  </h2>
<p>After testing all of this stuff I make some script for my personal writing pipeline (if I don&rsquo;t make some automation I feel bad) I fix some CSS of my site for the code part. I am a Backend Dev, so I don&rsquo;t share my CSS edit because it is something working but not so pretty to share&hellip;</p>
<p>After that I find myself wanting to have some way to cite a part of the post with a link (because I want to share a specific part of the post as a response to post/tweet/tooth on the web) and I search for something clean and usefull.</p>
<p>So I find a <a class="a-post interlink-script" href="https://www.bryanbraun.com/anchorjs/"   target="_blank">JS script&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 for adding deep anchor links to my post and I set it to add a deep anchor for every paragraph of the posts.</p>
<p><img  class="center-img u-photo "  src="mastodon.png" alt="mastodon.png"></p>
<p>And after all I check if I implement the <a class="a-post interlink-script" href="https://blog.joinmastodon.org/2024/07/highlighting-journalism-on-mastodon/"   target="_blank">meta tag for journalism for Mastodon&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 because I share a lot of stuff on Mastodon.</p>
<h2 id="final-consideration" class="no-underline ">
  <a href="#final-consideration">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Final consideration
  </a>
  </h2>
<p>I like my new configuration with the possibility to add Jupyter Notebook in my blog and this is the first Notebook I had to my Hugo Blog. I also like the idea that I can work for something else, make a Notebook and, only changing the data, make multiple article about something with the updated data every time I need to add the blog with the latest report for the dataset.</p>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/generate-post-with-img-for-hugo/</id><link rel="alternate" href="https://fundor333.com/post/2025/generate-post-with-img-for-hugo/"/><title>Generate Post With Img for Hugo</title><published>2025-07-12T08:36:34+02:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">How I create new post on Hugo and generate an image as cover</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>Some days ago I find a new post from a blog I follow about &ldquo;<a class="a-post interlink-script" href="https://www.burgeonlab.com/blog/hugo-and-wordpress-open-graph-meta-tags/"   target="_blank">Open Graph Meta Tags on Hugo and WordPress Blogs&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&rdquo; as a toot</p>








    
    
        
        
    

    
        <div class="toot">
            <div class="toot-header">
                <a class="toot-profile" href="https://fosstodon.org/@eclecticpassions" rel="noopener">
                    <img src="https://cdn.fosstodon.org/accounts/avatars/110/631/569/439/879/798/original/63c2880c18d2bab3.jpg"
                         alt="Avatar for @eclecticpassions@fosstodon.org"
                         loading="lazy">
                </a>
                <div class="toot-author">
                    <a class="toot-author-name"
                       href="https://fosstodon.org/@eclecticpassions"
                       rel="noopener">Naty</a>
                    <a class="toot-author-handle"
                       href="https://fosstodon.org/@eclecticpassions"
                       rel="noopener">@eclecticpassions@fosstodon.org</a>
                </div>
            </div>

            <div class="toot-content"><p>New <a href="https://fosstodon.org/tags/blogpost" class="mention hashtag" rel="tag">#<span>blogpost</span></a></p><p>➡️ <a href="https://www.burgeonlab.com/blog/hugo-and-wordpress-open-graph-meta-tags/" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://www.</span><span class="ellipsis">burgeonlab.com/blog/hugo-and-w</span><span class="invisible">ordpress-open-graph-meta-tags/</span></a></p><p>I often see bloggers on Mastodon with no images for their blog links or sometimes no link card at all (this was me not too long ago).</p><p>I&#39;ve been sorting out Open Graph meta tags for my three blogs (Hugo and WordPress) and I&#39;m happy to say it&#39;s all working great now! Read my post to get some tips! 👆 </p><p><a href="https://fosstodon.org/tags/BurgeonLab" class="mention hashtag" rel="tag">#<span>BurgeonLab</span></a><br /><a href="https://fosstodon.org/tags/blog" class="mention hashtag" rel="tag">#<span>blog</span></a> <a href="https://fosstodon.org/tags/blogging" class="mention hashtag" rel="tag">#<span>blogging</span></a> <a href="https://fosstodon.org/tags/blogs" class="mention hashtag" rel="tag">#<span>blogs</span></a> <a href="https://fosstodon.org/tags/hugo" class="mention hashtag" rel="tag">#<span>hugo</span></a> <a href="https://fosstodon.org/tags/wordpress" class="mention hashtag" rel="tag">#<span>wordpress</span></a> <a href="https://fosstodon.org/tags/webdev" class="mention hashtag" rel="tag">#<span>webdev</span></a> <a href="https://fosstodon.org/tags/opengraph" class="mention hashtag" rel="tag">#<span>opengraph</span></a></p></div>

            

            <div class="toot-footer">
                <a href="https://fosstodon.org@eclecticpassions/status/114818281454845557"
                   class="toot-date"
                   rel="noopener">3:18 PM · Jul 8, 2025</a>
            </div>
        </div>
    


<p>and I find I do the same thing and some more. I generate a default cover because I prefer to have a &ldquo;standard&rdquo; generated image or a specific image as the feature image. The image set in the settings is a default, a  &ldquo;if all other image fall use this&rdquo; kind of stuff.</p>
<h2 id="how-i-generate-the-post" class="no-underline ">
  <a href="#how-i-generate-the-post">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    How I generate the post?
  </a>
  </h2>
<p>When I write a post I launch a <a class="a-post interlink-script" href="https://fundor333.com/post/2021/the-team-makefile/"  >makefile command</a>
 and it launch two command for me:</p>
<ol>
<li>Generate a new post with hugo new</li>
<li>Generate a cover with my python script</li>
</ol>
<h2 id="some-code" class="no-underline ">
  <a href="#some-code">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Some code
  </a>
  </h2>
<p>For this project I use a font (<a class="a-post interlink-script" href="https://font.download/font/futura-book"   target="_blank">Futura Book font&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
) and a image where put the title and other thing of the post (for now only the title).
This is the image &ldquo;clean&rdquo;, without the text.</p>
<p><img  class="center-img u-photo "  src="cover-blank.jpg" alt="cover-blank.jpg"></p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> PIL <span style="color:#f92672">import</span> Image, ImageDraw, ImageFont  <span style="color:#75715e"># 👉️ Import modules from PIL</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">generate_img</span>(message: str, path: str):
</span></span><span style="display:flex;"><span>    font_path <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;Futura Book font.ttf&#34;</span>  <span style="color:#75715e"># 👉️ Font .ttf Path</span>
</span></span><span style="display:flex;"><span>    font_size <span style="color:#f92672">=</span> <span style="color:#ae81ff">100</span>  <span style="color:#75715e"># 👉️ Font Size</span>
</span></span><span style="display:flex;"><span>    img <span style="color:#f92672">=</span> Image<span style="color:#f92672">.</span>open(<span style="color:#e6db74">&#34;cover-blank.jpg&#34;</span>)  <span style="color:#75715e"># 👉️ Open Image</span>
</span></span><span style="display:flex;"><span>    dr <span style="color:#f92672">=</span> ImageDraw<span style="color:#f92672">.</span>Draw(img)  <span style="color:#75715e"># 👉️ Create New Image</span>
</span></span><span style="display:flex;"><span>    my_font <span style="color:#f92672">=</span> ImageFont<span style="color:#f92672">.</span>truetype(font_path, font_size)  <span style="color:#75715e"># 👉️ Initialize Font</span>
</span></span><span style="display:flex;"><span>    text_x <span style="color:#f92672">=</span> (img<span style="color:#f92672">.</span>width) <span style="color:#f92672">//</span> <span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>    text_y <span style="color:#f92672">=</span> (img<span style="color:#f92672">.</span>height) <span style="color:#f92672">//</span> <span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>    dr<span style="color:#f92672">.</span>text((text_x, text_y), message, font<span style="color:#f92672">=</span>my_font, fill<span style="color:#f92672">=</span>(<span style="color:#ae81ff">255</span>, <span style="color:#ae81ff">255</span>, <span style="color:#ae81ff">255</span>), anchor<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;mm&#34;</span>)
</span></span><span style="display:flex;"><span>    print(<span style="color:#e6db74">&#34;Generated content/&#34;</span> <span style="color:#f92672">+</span> path <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;/cover.png&#34;</span>)
</span></span><span style="display:flex;"><span>    img<span style="color:#f92672">.</span>save(<span style="color:#e6db74">&#34;content/&#34;</span> <span style="color:#f92672">+</span> path <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;/cover.png&#34;</span>)</span></span></code></pre></div><p>This script use Python (the library is PIL) and I set the fill parameters for a standard size OpenGraph image.</p>
<p>If you use a python script for generate new post you can implement this code inside of the script or you can add some code to make a command line to launch after your &ldquo;new post&rdquo; command.</p>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/add-minor-things-to-django/</id><link rel="alternate" href="https://fundor333.com/post/2025/add-minor-things-to-django/"/><title>Add Minor Things to Django for templating</title><published>2025-06-15T21:36:00+02:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">Some code I use in my django project for having some utility</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>More and more time I need some little thing for templating:</p>
<ul>
<li>The date fild of a form with the right input type for the page</li>
<li>A link with all the get parameters of the current page (form, paginator, etc&hellip;) and one added</li>
</ul>
<h2 id="the-code" class="no-underline ">
  <a href="#the-code">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The Code
  </a>
  </h2>
<p>This little code is mine but you can use it on all your project without thinking. If you find an error comment or webmention or replay with activity pub to my toot</p>
<h3 id="date-field-for-django-form" class="no-underline ">
  <a href="#date-field-for-django-form">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Date Field for Django Form
  </a>
  </h3>
<p>This is the widget I add to the django form for adding the right input type.</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> django.forms <span style="color:#f92672">import</span> TextInput
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">DateInput</span>(TextInput):
</span></span><span style="display:flex;"><span>    input_type <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;date&#34;</span></span></span></code></pre></div><p>I need this because the css/js framework I use add a data picker if you fill the input_type</p>
<h3 id="tag-for-changekeep-a-field" class="no-underline ">
  <a href="#tag-for-changekeep-a-field">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Tag for change/keep a field
  </a>
  </h3>
<p>Sometime I need to edit or add a get parameter in a link, like when you change the view from list to grid (for example).
So I coded this simple tag.</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> django <span style="color:#f92672">import</span> template
</span></span><span style="display:flex;"><span>register <span style="color:#f92672">=</span> template<span style="color:#f92672">.</span>Library()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">@register.simple_tag</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">url_replace</span>(request, field, value):
</span></span><span style="display:flex;"><span>    dict_ <span style="color:#f92672">=</span> request<span style="color:#f92672">.</span>GET<span style="color:#f92672">.</span>copy()
</span></span><span style="display:flex;"><span>    dict_[field] <span style="color:#f92672">=</span> value
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> dict_<span style="color:#f92672">.</span>urlencode()</span></span></code></pre></div><p>the only thing it does is change or add a value into the list of existing value.</p>
<p>For example</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-jinja" data-lang="jinja"><span style="display:flex;"><span>&lt;a href:&#34;https://fundor333.com?<span style="color:#75715e">{%</span> <span style="color:#66d9ef">url_replace_diff</span> request <span style="color:#e6db74">&#39;page&#39;</span> page_obj.page_number <span style="color:#75715e">%}</span>&#34;&gt;Link&lt;/a&gt;</span></span></code></pre></div><p>In this one I pass the pagination number to the new page. Why? Because I need to have the current page and all the serch filter also in the new page and this is the cleaner way WITHOUT using Js (I need control and Js is not controll)</p>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/so-this-is-why-i-sometime-reset-the-feed-reader-of-friends/</id><link rel="alternate" href="https://fundor333.com/post/2025/so-this-is-why-i-sometime-reset-the-feed-reader-of-friends/"/><title>So This Is Why I Sometime Reset the Feed Reader of Friends</title><published>2025-05-31T12:32:59+02:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">I find something I didn't know abouts feed rss and atom</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>I have a friend who read my blog using my feed. And sometime he pings me for some problem with the feed, like a drop of all the article as new</p>








    
    
        
        
    

    
        <div class="toot">
            <div class="toot-header">
                <a class="toot-profile" href="https://social.lol/@robb" rel="noopener">
                    <img src="https://fsn1.your-objectstorage.com/social-lol/accounts/avatars/109/523/762/776/095/110/original/548f0c6ecfffa5f1.jpg"
                         alt="Avatar for @robb@social.lol"
                         loading="lazy">
                </a>
                <div class="toot-author">
                    <a class="toot-author-name"
                       href="https://social.lol/@robb"
                       rel="noopener">Robb Knight</a>
                    <a class="toot-author-handle"
                       href="https://social.lol/@robb"
                       rel="noopener">@robb@social.lol</a>
                </div>
            </div>

            <div class="toot-content"><p>When I open my RSS reader and it has over 200 unread items, I know one of you has messed up your rss feeds</p><p>📌 <a href="https://rknight.me/notes/202501190902/" target="_blank" rel="nofollow noopener" translate="no"><span class="invisible">https://</span><span class="">rknight.me/notes/202501190902/</span><span class="invisible"></span></a></p></div>

            

            <div class="toot-footer">
                <a href="https://social.lol@robb/status/113854214799861227"
                   class="toot-date"
                   rel="noopener">9:04 AM · Jan 19, 2025</a>
            </div>
        </div>
    










    
    
        
        
    

    
        <div class="toot">
            <div class="toot-header">
                <a class="toot-profile" href="https://mastodon.social/@andreagrandi" rel="noopener">
                    <img src="https://files.mastodon.social/accounts/avatars/000/299/643/original/a1fe54a6da8006ce.jpg"
                         alt="Avatar for @andreagrandi@mastodon.social"
                         loading="lazy">
                </a>
                <div class="toot-author">
                    <a class="toot-author-name"
                       href="https://mastodon.social/@andreagrandi"
                       rel="noopener">Andrea Grandi 🦕</a>
                    <a class="toot-author-handle"
                       href="https://mastodon.social/@andreagrandi"
                       rel="noopener">@andreagrandi@mastodon.social</a>
                </div>
            </div>

            <div class="toot-content"><p><span class="h-card" translate="no"><a href="https://social.lol/@robb" class="u-url mention">@<span>robb</span></a></span> I think my friend <span class="h-card" translate="no"><a href="https://mastodon.social/@fundor333" class="u-url mention">@<span>fundor333</span></a></span> ears must be burning right now :D</p></div>

            

            <div class="toot-footer">
                <a href="https://mastodon.social@andreagrandi/status/113854638640440084"
                   class="toot-date"
                   rel="noopener">10:51 AM · Jan 19, 2025</a>
            </div>
        </div>
    


<p>And after read some other post with the same problem ( <a class="a-post interlink-script" href="https://rknight.me/notes/202501190902/"   target="_blank">Robb Knight problem with feed reader&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 <a class="a-post interlink-script" href="https://kevquirk.com/notes/20250528-1702?utm_source=fundor333.com&amp;utm_medium=link&amp;utm_campaign=blogging&amp;ref=fundor333.com"   target="_blank">Kev other problem with feed reader&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 ) I understand a little this: Atom is newer and superior than Rss.</p>
<h2 id="atom-vs-rss" class="no-underline ">
  <a href="#atom-vs-rss">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Atom vs Rss
  </a>
  </h2>
<p>Atom is the newer one, born after the RSS and after fix a lot of the RSS bugs like:</p>
<ul>
<li>You have a strict format for checking and validation in Atom</li>
<li>RSS is simpler but less strict and it is riddled with ambiguities which lead to inconsistency of interpretation</li>
<li>You have a unique id for the feed in Atom</li>
</ul>
<p>The last one is the one I was searching&hellip;</p>
<h2 id="the-answer" class="no-underline ">
  <a href="#the-answer">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The Answer
  </a>
  </h2>
<p>The feed reader find the new feed (new because you change the url or you change the serverside code) and check:</p>
<ul>
<li>Atom Feed: the reader find the same ID so is the same feed</li>
<li>RSS Feed: the reader don&rsquo;t find the ID and find something different not in the items part so it is a new one</li>
</ul>
<p>So I add the JsonFeed and AtomFeed to the blog for give the reader multiple option for the feed!</p>
<p>You can find all at <a class="a-post interlink-script" href="https://fundor333.com/feeds/"  >this link</a>
</p>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/webring-into-2025/</id><link rel="alternate" href="https://fundor333.com/post/2025/webring-into-2025/"/><title>Having a Webring Into 2025</title><published>2025-05-24T12:11:42+02:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">What are the webrings and why you need to be in one into 2025</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>Once upon a time Internet was different. No social media, no search engine, no fiber&hellip;
So how people find new site? Because the internet users share link into the blogs.</p>
<p>And one of the best way to share other blog without filling a webpage with links was the WebRing.</p>
<h2 id="webring" class="no-underline ">
  <a href="#webring">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    WebRing?
  </a>
  </h2>
<p>For <a class="a-post interlink-script" href="https://en.wikipedia.org/wiki/Webring"   target="_blank">Wikipedia&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 a Webring is</p>
<blockquote>
<p>A webring (or web ring) is a collection of websites linked together in a circular structure, usually organized around a specific theme, and often educational or social.[1] They were popular in the 1990s and early 2000s, particularly among amateur websites.</p>
</blockquote>
<p>Today, with the Search Engin owned by the big tec and the AI being part of the mayor Search Engine we need more than ever list of human web pages to read and less AI generated post.</p>
<h2 id="for-example" class="no-underline ">
  <a href="#for-example">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    For example?
  </a>
  </h2>
<p>Some example of WebRing? This are some type of WebRing</p>
<ul>
<li><em>A themed WebRing</em> Like a <a class="a-post interlink-script" href="https://djangowebring.com/"   target="_blank">WebRing about Python&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
</li>
<li><em>An Inspirational WebRing</em> Like <a class="a-post interlink-script" href="https://webring.xxiivv.com/"   target="_blank">one for dev and artist&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
</li>
<li><em>One for Group of People</em> Like <a class="a-post interlink-script" href="https://webring.recurse.com/"   target="_blank">one for onl;y personal site&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
</li>
<li><em>One for a Community</em> Like <a class="a-post interlink-script" href="https://xn--sr8hvo.ws/directory"   target="_blank">one about IndieWeb&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
</li>
</ul>
<p>If you don&rsquo;t find a WebRing for your &ldquo;community&rdquo;, you can create a new one with a tutorial ( <a class="a-post interlink-script" href="https://mxb.dev/blog/webring-kit/"   target="_blank">A Webring Kit&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 ) and a framework for making WebRing ( <a class="a-post interlink-script" href="https://github.com/maxboeck/webring"   target="_blank">GitHub Repo from A Webring Kit&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 )</p>
<p>Remember, this is a free way to have more traffic inside your site and for build your community</p>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/django-generate-barcode-with-reportlab/</id><link rel="alternate" href="https://fundor333.com/post/2025/django-generate-barcode-with-reportlab/"/><title>Django Generate Barcode With Reportlab</title><published>2025-05-19T12:30:00+02:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">Tutorial to build pages and pages of barcode for labeling stuffs</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>After <a class="a-post interlink-script" href="https://fundor333.com/post/2022/django-with-barcode-and-qrcode/"   target="_blank">Django With Barcode and Qrcode&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 and <a class="a-post interlink-script" href="https://fundor333.com/post/2022/django-return-pdf-with-reportlab/"   target="_blank">Django Return Pdf With Reportlab&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 I need something new in my Django server. I need a barcode generator for labeling stuffs.</p>
<h2 id="the-problem" class="no-underline ">
  <a href="#the-problem">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The problem
  </a>
  </h2>
<p>Every code is a solution to a pratical problem. In this case I need to make the barcode labels with text for keep an inventory.
The basic solution is generate a pdf/img file to print into sticker&rsquo;s paper and cut it after.</p>
<p><img  class="center-img u-photo "  src="barcode.png" alt="Barcode Example"></p>
<p>So, I need the data to convert into lable (the string on top to the barcode) and the barcode (or the qrcode) as in the screenshot, so I wrote this code for do it for pages and ready to print and stick it all around the world!</p>
<h2 id="code" class="no-underline ">
  <a href="#code">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Code
  </a>
  </h2>
<h3 id="the-view" class="no-underline ">
  <a href="#the-view">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The view
  </a>
  </h3>
<p>This code is the view for generating download link for the pdf with all the barcode.</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> django.views.generic <span style="color:#f92672">import</span> View
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ExampleBarcodePdf</span>(View):
</span></span><span style="display:flex;"><span>    bar_height <span style="color:#f92672">=</span> <span style="color:#66d9ef">None</span>
</span></span><span style="display:flex;"><span>    position_text_y <span style="color:#f92672">=</span> <span style="color:#66d9ef">None</span>
</span></span><span style="display:flex;"><span>    filename <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;ExampleBarCode.pdf&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">get</span>(self, request, <span style="color:#f92672">*</span>args, <span style="color:#f92672">**</span>kwargs):
</span></span><span style="display:flex;"><span>      super()<span style="color:#f92672">.</span>get(request, <span style="color:#f92672">*</span>args, <span style="color:#f92672">**</span>kwargs)
</span></span><span style="display:flex;"><span>      response <span style="color:#f92672">=</span> HttpResponse(content_type<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;application/pdf&#34;</span>)
</span></span><span style="display:flex;"><span>      response[<span style="color:#e6db74">&#34;Content-Disposition&#34;</span>] <span style="color:#f92672">=</span> (
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#39;attachment; filename=&#34;&#39;</span> <span style="color:#f92672">+</span> self<span style="color:#f92672">.</span>filename <span style="color:#f92672">+</span> <span style="color:#e6db74">&#39;&#34;&#39;</span>
</span></span><span style="display:flex;"><span>      )
</span></span><span style="display:flex;"><span>      a4p <span style="color:#f92672">=</span> A4PrinterBarcode()
</span></span><span style="display:flex;"><span>      pdf <span style="color:#f92672">=</span> a4p<span style="color:#f92672">.</span>get_pdf(
</span></span><span style="display:flex;"><span>          buffer<span style="color:#f92672">=</span>BytesIO(),
</span></span><span style="display:flex;"><span>          datas<span style="color:#f92672">=</span>[{barcode:<span style="color:#e6db74">&#34;0000000000000&#34;</span>, <span style="color:#e6db74">&#34;label&#34;</span>}, {<span style="color:#e6db74">&#34;999999999999&#34;</span>, <span style="color:#e6db74">&#34;other label&#34;</span>}],
</span></span><span style="display:flex;"><span>          bar_height<span style="color:#f92672">=</span>self<span style="color:#f92672">.</span>bar_height,
</span></span><span style="display:flex;"><span>          position_text_y<span style="color:#f92672">=</span>self<span style="color:#f92672">.</span>position_text_y,
</span></span><span style="display:flex;"><span>      )
</span></span><span style="display:flex;"><span>      response<span style="color:#f92672">.</span>write(pdf)
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">return</span> response</span></span></code></pre></div><h3 id="the-pdf-generator" class="no-underline ">
  <a href="#the-pdf-generator">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The pdf generator
  </a>
  </h3>
<p>This is the &ldquo;printer&rdquo; the code for generate pdf.
After the import you find the constant with define the pdf.ß</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> reportlab.graphics.barcode.eanbc <span style="color:#f92672">import</span> Ean13BarcodeWidget
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> reportlab.graphics.shapes <span style="color:#f92672">import</span> Drawing
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> reportlab.graphics.shapes <span style="color:#f92672">import</span> String
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> reportlab.lib.pagesizes <span style="color:#f92672">import</span> A4
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> reportlab.pdfgen <span style="color:#f92672">import</span> canvas
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>PAGESIZE <span style="color:#f92672">=</span> A4
</span></span><span style="display:flex;"><span>NUM_LABELS_X <span style="color:#f92672">=</span> <span style="color:#ae81ff">3</span>
</span></span><span style="display:flex;"><span>NUM_LABELS_Y <span style="color:#f92672">=</span> <span style="color:#ae81ff">8</span>
</span></span><span style="display:flex;"><span>BAR_WIDTH <span style="color:#f92672">=</span> <span style="color:#ae81ff">1.5</span>
</span></span><span style="display:flex;"><span>BAR_HEIGHT <span style="color:#f92672">=</span> <span style="color:#ae81ff">51.0</span>
</span></span><span style="display:flex;"><span>TEXT_Y <span style="color:#f92672">=</span> <span style="color:#ae81ff">80</span>
</span></span><span style="display:flex;"><span>BARCODE_Y <span style="color:#f92672">=</span> <span style="color:#ae81ff">17</span>
</span></span><span style="display:flex;"><span>FONT_SIZE <span style="color:#f92672">=</span> <span style="color:#ae81ff">8</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>LABEL_WIDTH <span style="color:#f92672">=</span> PAGESIZE[<span style="color:#ae81ff">0</span>] <span style="color:#f92672">/</span> NUM_LABELS_X
</span></span><span style="display:flex;"><span>LABEL_HEIGHT <span style="color:#f92672">=</span> PAGESIZE[<span style="color:#ae81ff">1</span>] <span style="color:#f92672">/</span> NUM_LABELS_Y
</span></span><span style="display:flex;"><span>SHEET_TOP <span style="color:#f92672">=</span> PAGESIZE[<span style="color:#ae81ff">1</span>]
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">A4PrinterBarcode</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">generate_label</span>(
</span></span><span style="display:flex;"><span>        self,
</span></span><span style="display:flex;"><span>        ean13: str,
</span></span><span style="display:flex;"><span>        description: str,
</span></span><span style="display:flex;"><span>        label_w: float <span style="color:#f92672">=</span> <span style="color:#ae81ff">0.0</span>,
</span></span><span style="display:flex;"><span>        label_h: float <span style="color:#f92672">=</span> <span style="color:#ae81ff">0.0</span>,
</span></span><span style="display:flex;"><span>        bar_with: float <span style="color:#f92672">=</span> BAR_WIDTH,
</span></span><span style="display:flex;"><span>        bar_height: float <span style="color:#f92672">=</span> BAR_HEIGHT,
</span></span><span style="display:flex;"><span>        postion_text_y: float <span style="color:#f92672">=</span> TEXT_Y,
</span></span><span style="display:flex;"><span>        font_size: int <span style="color:#f92672">=</span> FONT_SIZE,
</span></span><span style="display:flex;"><span>    ) <span style="color:#f92672">-&gt;</span> Drawing:
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;&#34;&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        Generate a drawing with EAN-13 barcode and descriptive text.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        :param ean13: The EAN-13 Code.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        :type ean13: str
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        :param description: Short product description.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        :type description: str
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        :return: Drawing with barcode and description
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        :rtype: Drawing
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        &#34;&#34;&#34;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> label_w <span style="color:#f92672">==</span> <span style="color:#ae81ff">0.0</span>:
</span></span><span style="display:flex;"><span>            label_w <span style="color:#f92672">=</span> A4[<span style="color:#ae81ff">0</span>] <span style="color:#f92672">/</span> NUM_LABELS_X
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> label_h <span style="color:#f92672">==</span> <span style="color:#ae81ff">0.0</span>:
</span></span><span style="display:flex;"><span>            label_h <span style="color:#f92672">=</span> A4[<span style="color:#ae81ff">1</span>] <span style="color:#f92672">/</span> NUM_LABELS_Y
</span></span><span style="display:flex;"><span>        text <span style="color:#f92672">=</span> String(
</span></span><span style="display:flex;"><span>            <span style="color:#ae81ff">0</span>,
</span></span><span style="display:flex;"><span>            postion_text_y,
</span></span><span style="display:flex;"><span>            description,
</span></span><span style="display:flex;"><span>            fontName<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Helvetica&#34;</span>,
</span></span><span style="display:flex;"><span>            fontSize<span style="color:#f92672">=</span>font_size,
</span></span><span style="display:flex;"><span>            textAnchor<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;middle&#34;</span>,
</span></span><span style="display:flex;"><span>        )
</span></span><span style="display:flex;"><span>        text<span style="color:#f92672">.</span>x <span style="color:#f92672">=</span> label_w <span style="color:#f92672">/</span> <span style="color:#ae81ff">2</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        barcode <span style="color:#f92672">=</span> Ean13BarcodeWidget(ean13)
</span></span><span style="display:flex;"><span>        barcode<span style="color:#f92672">.</span>barWidth <span style="color:#f92672">=</span> bar_with
</span></span><span style="display:flex;"><span>        barcode<span style="color:#f92672">.</span>barHeight <span style="color:#f92672">=</span> bar_height
</span></span><span style="display:flex;"><span>        _, _, bw, _ <span style="color:#f92672">=</span> barcode<span style="color:#f92672">.</span>getBounds()
</span></span><span style="display:flex;"><span>        barcode<span style="color:#f92672">.</span>x <span style="color:#f92672">=</span> (label_w <span style="color:#f92672">-</span> bw) <span style="color:#f92672">/</span> <span style="color:#ae81ff">2</span>  <span style="color:#75715e"># center barcode</span>
</span></span><span style="display:flex;"><span>        barcode<span style="color:#f92672">.</span>y <span style="color:#f92672">=</span> <span style="color:#ae81ff">18</span>  <span style="color:#75715e"># spacing from label bottom (pt)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        label_drawing <span style="color:#f92672">=</span> Drawing(label_w, label_h)
</span></span><span style="display:flex;"><span>        label_drawing<span style="color:#f92672">.</span>add(text)
</span></span><span style="display:flex;"><span>        label_drawing<span style="color:#f92672">.</span>add(barcode)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> label_drawing
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">get_pdf</span>(
</span></span><span style="display:flex;"><span>        self,
</span></span><span style="display:flex;"><span>        buffer,
</span></span><span style="display:flex;"><span>        datas: list,
</span></span><span style="display:flex;"><span>        bar_height: float <span style="color:#f92672">=</span> <span style="color:#66d9ef">None</span>,
</span></span><span style="display:flex;"><span>        position_text_y: float <span style="color:#f92672">=</span> <span style="color:#66d9ef">None</span>,
</span></span><span style="display:flex;"><span>    ) <span style="color:#f92672">-&gt;</span> bytes:
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> bar_height <span style="color:#f92672">is</span> <span style="color:#66d9ef">None</span> <span style="color:#f92672">or</span> bar_height <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">0</span>:
</span></span><span style="display:flex;"><span>            bar_height <span style="color:#f92672">=</span> BAR_HEIGHT
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> position_text_y <span style="color:#f92672">is</span> <span style="color:#66d9ef">None</span> <span style="color:#f92672">or</span> position_text_y <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">0</span>:
</span></span><span style="display:flex;"><span>            position_text_y <span style="color:#f92672">=</span> TEXT_Y
</span></span><span style="display:flex;"><span>        p <span style="color:#f92672">=</span> canvas<span style="color:#f92672">.</span>Canvas(buffer)
</span></span><span style="display:flex;"><span>        j <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">for</span> _ <span style="color:#f92672">in</span> range(len(datas) <span style="color:#f92672">//</span> (NUM_LABELS_X <span style="color:#f92672">*</span> NUM_LABELS_Y) <span style="color:#f92672">+</span> <span style="color:#ae81ff">1</span>):
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">for</span> u <span style="color:#f92672">in</span> range(<span style="color:#ae81ff">0</span>, NUM_LABELS_Y):
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">for</span> i <span style="color:#f92672">in</span> range(<span style="color:#ae81ff">0</span>, NUM_LABELS_X):
</span></span><span style="display:flex;"><span>                    <span style="color:#66d9ef">if</span> j <span style="color:#f92672">&lt;</span> len(datas):
</span></span><span style="display:flex;"><span>                        data <span style="color:#f92672">=</span> datas[j]
</span></span><span style="display:flex;"><span>                        cb <span style="color:#f92672">=</span> data<span style="color:#f92672">.</span>barcode
</span></span><span style="display:flex;"><span>                        desc <span style="color:#f92672">=</span> data<span style="color:#f92672">.</span>label
</span></span><span style="display:flex;"><span>                        <span style="color:#66d9ef">try</span>:
</span></span><span style="display:flex;"><span>                            label <span style="color:#f92672">=</span> self<span style="color:#f92672">.</span>generate_label(
</span></span><span style="display:flex;"><span>                                ean13<span style="color:#f92672">=</span>cb,
</span></span><span style="display:flex;"><span>                                description<span style="color:#f92672">=</span>desc,
</span></span><span style="display:flex;"><span>                                bar_height<span style="color:#f92672">=</span>bar_height,
</span></span><span style="display:flex;"><span>                                postion_text_y<span style="color:#f92672">=</span>position_text_y,
</span></span><span style="display:flex;"><span>                            )
</span></span><span style="display:flex;"><span>                            x <span style="color:#f92672">=</span> i <span style="color:#f92672">*</span> LABEL_WIDTH
</span></span><span style="display:flex;"><span>                            y <span style="color:#f92672">=</span> SHEET_TOP <span style="color:#f92672">-</span> LABEL_HEIGHT <span style="color:#f92672">-</span> u <span style="color:#f92672">*</span> LABEL_HEIGHT
</span></span><span style="display:flex;"><span>                            label<span style="color:#f92672">.</span>drawOn(p, x, y)
</span></span><span style="display:flex;"><span>                        <span style="color:#66d9ef">except</span> <span style="color:#a6e22e">AttributeError</span>:
</span></span><span style="display:flex;"><span>                            <span style="color:#66d9ef">pass</span>
</span></span><span style="display:flex;"><span>                        j <span style="color:#f92672">+=</span> <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>            p<span style="color:#f92672">.</span>showPage()
</span></span><span style="display:flex;"><span>        p<span style="color:#f92672">.</span>save()
</span></span><span style="display:flex;"><span>        pdf <span style="color:#f92672">=</span> buffer<span style="color:#f92672">.</span>getvalue()
</span></span><span style="display:flex;"><span>        buffer<span style="color:#f92672">.</span>close()
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> pdf</span></span></code></pre></div><h2 id="so-how-do-a4printerbarcode-work-" class="no-underline ">
  <a href="#so-how-do-a4printerbarcode-work-">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    So how do <em>A4PrinterBarcode</em> work ?
  </a>
  </h2>
<p>The main concept of this class is to generate the &ldquo;labels&rdquo; (barcode and text) and put them into a grid pattern.
So we have two function:</p>
<ul>
<li><em>generate_label</em> generate the single &ldquo;label&rdquo;, one of the time</li>
<li><em>get_pdf</em> generate the pdf putting the &ldquo;labels&rdquo; in a grid pattern</li>
</ul>
<p>If you need, this class can be used without Django, in something like a <a class="a-post interlink-script" href="https://fundor333.com/post/2023/why-i-stop-making-script-and-start-to-make-bash-terminal-commands/"   target="_blank">tool for terminal&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
</p>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/activitypub-vs-webmention-do-you-need-them/</id><link rel="alternate" href="https://fundor333.com/post/2025/activitypub-vs-webmention-do-you-need-them/"/><title>Activitypub vs Webmention Do You Need Them ?</title><published>2025-05-16T07:23:27+02:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">Some personal thinking about webmention and activitypub and how to use/combine them</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>I have a lot of article about webmention because I implement them on my site/blog. And I use them ad comment, like sistem and more. But more I read about ActivityPub and the Feedverse more I thing it can be a good think to implement it insite your site for your content and for share to the Feedverse.</p>
<h2 id="why-do-it" class="no-underline ">
  <a href="#why-do-it">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Why do it?
  </a>
  </h2>
<p>One of the best arguments for having a personal ActivityPub site/server is you having a unique identity, don&rsquo;t fragmenting your identity<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> on multiple Feedverse accounts.</p>
<p>But I implemented Webmention and stuff like <a class="a-post interlink-script" href="https://brid.gy/"   target="_blank">Brid&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 for having the likes, comments and all the stuff I have in the ActivityPub about my posts. So why I need to do it?</p>
<p>If I need more reference to your post/article on the Feedverse, Mastodon has a function<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> for show your account under your link making a link to your profile. It also easy to set up and some platform has a plugin for it (like for Wordpress) or easy articole online for your favorite platfome (for example this is for <a class="a-post interlink-script" href="https://onemanandhisblog.com/2024/10/adding-a-mastodon-author-to-ghost/"   target="_blank">Ghost&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
).</p>
<p>But if you aren&rsquo;t in the FeedVerse you are loosing in a way in to a social media moviment which is groing with major players studing and testing the ground (Meta, Tumblr, with also X/Twitter looking without public testing) and more and more time pass, more and more service integrate the ActivityPub in their social/site/service.</p>
<p>I also have a lot of attention from the tech blogger, where if you don&rsquo;t write about excitement<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> you are writing about how to implement ActivityPub on your site[^4].</p>
<h2 id="and-so-i-need-to-integrate-this-new-stuff-into-my-site" class="no-underline ">
  <a href="#and-so-i-need-to-integrate-this-new-stuff-into-my-site">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    And so? I need to integrate this new stuff into my site?
  </a>
  </h2>
<p>No and yes. If you want a presence in the FeedVerse you need to be active also there but no with a integration with the ActivityPub protocol: you can share it like the &ldquo;old days&rdquo;.</p>
<p>Also having a ActivityPub implementation somewhere is a resource draining server so you need to think about how much money and time you want to spend on it.</p>
<p>In the end Webmention and ActivityPub are two way to have more interaction with your site but you also need to now which interaction is better for your site.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Two article about it <a class="a-post interlink-script" href="[Federated/Fragmentated]%28https://cogdogblog.com/2024/11/federated-fragmentated/?ref=jadin.me%29"  >Federated/Fragmentated</a>
 and <a class="a-post interlink-script" href="https://jadin.me/who-is-this/"   target="_blank">Who is this?&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Post about it <a class="a-post interlink-script" href="https://blog.joinmastodon.org/2024/07/highlighting-journalism-on-mastodon/"   target="_blank">Highlighting journalism on Mastodon&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>Some article about excitement <a class="a-post interlink-script" href="https://jadin.me/why-im-excited-about-ghost-getting-activitypub-support/"   target="_blank">Why I&rsquo;m excited about Ghost getting ActivityPub support&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 <a class="a-post interlink-script" href="https://onemanandhisblog.com/2025/03/the-federated-one-man-his-blog/"   target="_blank">The federated One Man &amp; His Blog&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>

[^4] For example this article <a class="a-post interlink-script" href="https://maho.dev/2025/03/a-guide-to-implementing-activitypub-in-a-static-site-or-any-website-q1-2025-updates/"   target="_blank">A Guide to Implementing ActivityPub in a Static Site (or Any Website) - Q1 2025 Updates&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/csv-from-django/</id><link rel="alternate" href="https://fundor333.com/post/2025/csv-from-django/"/><title>Csv From Django</title><published>2025-04-18T12:23:09+02:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">A little class view for return CSV</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>Some time you need to export a file into a specific format for some use like upload to the old system.
In this case I need to have a CSV file which another software fill.</p>
<h2 id="the-code" class="no-underline ">
  <a href="#the-code">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The code
  </a>
  </h2>
<p>I wrote a ClassView for this case, this class. <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">CsvCarsDownload</span>(View):
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">get</span>(self, request, <span style="color:#f92672">*</span>args, <span style="color:#f92672">**</span>kwargs):
</span></span><span style="display:flex;"><span>        response <span style="color:#f92672">=</span> HttpResponse(content_type<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;text/csv&#34;</span>)
</span></span><span style="display:flex;"><span>        response[<span style="color:#e6db74">&#34;Content-Disposition&#34;</span>] <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;attachment; filename=&#34;cars.csv&#34;&#39;</span>
</span></span><span style="display:flex;"><span>        my_dict <span style="color:#f92672">=</span> [{
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;brand&#34;</span>: <span style="color:#e6db74">&#34;Ford&#34;</span>,
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;model&#34;</span>: <span style="color:#e6db74">&#34;Mustang&#34;</span>,
</span></span><span style="display:flex;"><span>          <span style="color:#e6db74">&#34;year&#34;</span>: <span style="color:#ae81ff">1964</span>
</span></span><span style="display:flex;"><span>        }]
</span></span><span style="display:flex;"><span>        writer <span style="color:#f92672">=</span> csv<span style="color:#f92672">.</span>DictWriter(
</span></span><span style="display:flex;"><span>            response, dialect<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;excel&#34;</span>, fieldnames<span style="color:#f92672">=</span>my_dict[<span style="color:#ae81ff">0</span>]<span style="color:#f92672">.</span>keys()
</span></span><span style="display:flex;"><span>        )
</span></span><span style="display:flex;"><span>        writer<span style="color:#f92672">.</span>writeheader()
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">for</span> element <span style="color:#f92672">in</span> my_dict:
</span></span><span style="display:flex;"><span>          writer<span style="color:#f92672">.</span>writerow(element)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> response</span></span></code></pre></div><p>You can change the type of the the CSV changing the <strong>dialect</strong> with one of the type of the CSV dialect (excel, excel_tab, unix_dialect) and changing the <strong>my_dict</strong> with any type of list of dict.</p>
<p>With this code you can use any Class Mixin from others module for add other functions like permission supports or loggeer configurations.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>I don&rsquo;t like coding functional view so I only code ClassViews&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/re-using-re-in-blog-titles/</id><link rel="alternate" href="https://fundor333.com/post/2025/re-using-re-in-blog-titles/"/><title>Re:Using 'Re:' in Blog Titles</title><published>2025-04-14T21:00:21+02:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">Blogpost about how to write a post response</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>Following the post from <a class="a-post interlink-script" href="https://rubenerd.com/using-re-in-blog-titles/"   target="_blank">Ruben&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 I start imitating this idea and expand on it.</p>
<blockquote>
<p>&ldquo;Imitation is the sincerest form of flattery that mediocrity can pay to greatness.&rdquo;</p>
<p>Oscar Wilde</p>
</blockquote>
<p>The basic idea come from a post by <a class="a-post interlink-script" href="https://brandons-journal.com/re-im-part-of-the-problem/"   target="_blank">Brandon&rsquo;s Journal&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 where Brandon response to an article and use the <strong>Re:</strong> prefix, like a email threads in the title of the post&hellip;</p>
<p>And I add a microformat following the IndieWeb stuff for the response tags.
So my post which are a &ldquo;Re:&rdquo; will have a <strong>u-in-reply-to</strong> in the class of the links for implementing the IndieWeb, like in this article.</p>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/pages-you-need-in-your-blog/</id><link rel="alternate" href="https://fundor333.com/post/2025/pages-you-need-in-your-blog/"/><title>Pages You Need in Your Blog</title><published>2025-04-06T13:42:47+02:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">There are some page you need to have in your blog if your blog is for human</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>More and more blog I read and more and more I find that a lot of the dev blog and personal blog on the web has a lot of common pages but not the old <em>About</em> or <em>Contacts</em> so I make this list of interesting pages types.</p>
<h2 id="blogroll" class="no-underline ">
  <a href="#blogroll">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Blogroll
  </a>
  </h2>
<p>One of the best page I find on a blog. This is a page where the blogger show a link of site/blog (a html page or a Opml file) of interesting stuff.</p>
<p>I find iteresting because I can have an idea about the blogger interest and I can find new and different source of post.</p>
<p>Mine is <a class="a-post interlink-script" href="/blogroll"  >here</a>
</p>
<h2 id="connect" class="no-underline ">
  <a href="#connect">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Connect
  </a>
  </h2>
<p>Half of the old <em>About Us</em> page. In this page the blog put all the link needed to follow and/or contact the author on the classic way (email,&hellip;) and the new social way (mastodon, twitter, etc&hellip;)</p>
<p>Mine is <a class="a-post interlink-script" href="/connect"  >here</a>
</p>
<h2 id="feeds" class="no-underline ">
  <a href="#feeds">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Feeds
  </a>
  </h2>
<p>Inspired by <a class="a-post interlink-script" href="https://marcus.io/blog/making-rss-more-visible-again-with-slash-feeds"   target="_blank">this post&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 the <em>feeds</em> page is the most functional page for user on a site.
This page has all the feeds&rsquo; links for the blog and other service the blogger is showing. Sometime some feeds aren&rsquo;t from the blog but from other platform of the blogger.</p>
<p>Mine is <a class="a-post interlink-script" href="/feeds"  >here</a>
</p>
<h2 id="now" class="no-underline ">
  <a href="#now">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Now
  </a>
  </h2>
<p>The other half of the <em>About Us</em> page. It come from an <a class="a-post interlink-script" href="https://nownownow.com/about"   target="_blank">idea&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 about having a space (in this case a page on a site) about what are you doing with your life and interest.
In this way you can also use it for showing off your little project or have a space for fundraising your project.</p>
<p>Sometime I search on Google now pages for find new project and others things.</p>
<p>Mine is <a class="a-post interlink-script" href="/now"  >here</a>
</p>
<h2 id="uses" class="no-underline ">
  <a href="#uses">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Uses
  </a>
  </h2>
<p>The strange page (for me). There is a <a class="a-post interlink-script" href="https://uses.tech/"   target="_blank">uses site&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 where you can send your <em>Uses</em> link where you share what tech you use every day or for the project. In this way you can check what tech other people use and for what.</p>
<p>In this type of pages I love to check what kind of coding and photo set up they have.</p>
<p>Mine is <a class="a-post interlink-script" href="/uses"  >here</a>
</p>
<h2 id="so" class="no-underline ">
  <a href="#so">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    So?
  </a>
  </h2>
<p>So I suggest to have some of this pages on your blog if you thing of your blog as a personal blog. It can be usefull for start a conversation online or for having a place to send people for answer about your works and your stuffs.</p>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/an-easy-way-to-start-a-life-in-the-indieweb/</id><link rel="alternate" href="https://fundor333.com/post/2025/an-easy-way-to-start-a-life-in-the-indieweb/"/><title>An Easy Way to Start a Life in the IndieWeb</title><published>2025-01-31T12:46:00+01:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">A tool to start a life on the IndieWeb leaving the social media behind</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>There are more and more post about the Indieweb and what you can find in a indiweb site/blog<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> but I didn&rsquo;t find an easy tutorial for starting with IndiWeb. But first:
What is the IndieWeb?</p>
<h2 id="indieweb-the-definition" class="no-underline ">
  <a href="#indieweb-the-definition">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    IndieWeb the definition
  </a>
  </h2>
<p>I thing that, to explain IndieWeb we need two definition: one from a more &ldquo;anthropological&rdquo; point of view and one from a &ldquo;tecnical/it&rdquo; point of view</p>
<h3 id="anthropological-definition" class="no-underline ">
  <a href="#anthropological-definition">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Anthropological definition
  </a>
  </h3>
<blockquote>
<p>The #IndieWeb is for everyone, everyone who wants to be part of the world-wide-web of interconnected people. The social internet of people, a network of networks of people, connected peer-to-peer in human-scale groups, communities of locality and affinity.</p>
</blockquote>
<h3 id="tecnicalit-definition" class="no-underline ">
  <a href="#tecnicalit-definition">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Tecnical/It definition
  </a>
  </h3>
<blockquote>
<p>The IndieWeb is a community of independent and personal websites connected by open standards, based on the principles of: owning your domain and using it as your primary online identity, publishing on your own site first (optionally elsewhere), and owning your content.</p>
</blockquote>
<h3 id="so-why-i-need-to-be-in-the-indieweb" class="no-underline ">
  <a href="#so-why-i-need-to-be-in-the-indieweb">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    So, why I need to be in the Indieweb?
  </a>
  </h3>
<p><img  class="center-img u-photo "  src="pill.png" alt="red pill blue pill"></p>
<p>You don&rsquo;t need to be in. You need to choose <strong>red pill</strong> or <strong>blue pill</strong></p>
<p><strong>Red Pill</strong>: If you want to have a look inside the mirror and, because you have something to say online, you need to have a personal domain and a space where you have the control and own your content and</p>
<blockquote>
<p>You stay in Wonderland and I show you how deep the rabbit hole goes</p>
</blockquote>
<p><strong>Blue Pill</strong>: You keep the social network account you have and</p>
<blockquote>
<p>The story ends, you wake up in your bed and believe whatever you want to believe</p>
</blockquote>
<h2 id="red-pill-now-what" class="no-underline ">
  <a href="#red-pill-now-what">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Red Pill, now what?
  </a>
  </h2>
<p>There are multiple things to do and tools to choose for you if you want to start with IndieWeb so I suggest a site which help you understand what you need to do and what to choose.</p>
<p>This site is <a class="a-post interlink-script" href="https://unplatform.fromthesuperhighway.com/"   target="_blank">Unplatform&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 from the people of the <a class="a-post interlink-script" href="fromthesuperhighway.com"  >fromthesuperhighway</a>
.</p>
<p>This is a simple way to understand and start with the <strong>red pill</strong> and with a complete explanation for every tool you choose so you can have the easyest way to became an IndieWeb user.</p>
<p>Have a nice IndieWeb expirience</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a class="a-post interlink-script" href="https://indieweb.org/"   target="_blank">Indiweb&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
, <a class="a-post interlink-script" href="https://news.ycombinator.com/item?id=26950009"   target="_blank">The IndieWeb is a people-focused alternative to the “corporate web”&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
, <a class="a-post interlink-script" href="https://blog.rubenwardy.com/2023/10/10/hello-indieweb/"   target="_blank">I have joined the IndieWeb&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
, <a class="a-post interlink-script" href="https://darthmall.net/2024/indieweb-is-for-devs/"   target="_blank">The IndieWeb is for Developers&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
, <a class="a-post interlink-script" href="https://werd.io/2024/the-indieweb-is-for-everyone"   target="_blank">The indieweb is for everyone&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/substack-vs-medium-what-is-better-for-a-coder/</id><link rel="alternate" href="https://fundor333.com/post/2025/substack-vs-medium-what-is-better-for-a-coder/"/><title>Substack vs Medium: What Is Better for a Coder?</title><published>2025-01-27T12:02:52+01:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">If you are a developer where do you blog better? Medium or Substack?</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>I am first and most a Developer and a Coder and I think that coding and developing software (site, app, AI, etc&hellip;) need to be a share experience.
So I think a dev must share knowledge in the web. Somebody help people on StackOverflow and someone (like me) blogs.</p>
<p>In the last <em>X</em> years<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> I understand the important of blogging and why a dev or a coder need to write a blog/newsletter/magazine about what is doing<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> and how big time sink is developing and maintaining a custom blog so I have this question:</p>
<blockquote>
<p>For sharing Dev/Coding experiences is better Medium or StackOverflow?<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></p>
</blockquote>
<h2 id="we-need-a-generic-dev" class="no-underline ">
  <a href="#we-need-a-generic-dev">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    We need a &ldquo;generic&rdquo; Dev!
  </a>
  </h2>
<p>This is <em>Bob</em>. <em>Bob</em> is a BackEnd Developer, a Python Developer and he is learning some FrontEnd stuffs. So he wants to write about what he knows, what is learning and his doubts.</p>
<p><img  class="center-img u-photo "  src="bob.png" alt="Bob Avatar"></p>
<h3 id="what-a-dev-need-to-share-in-a-post" class="no-underline ">
  <a href="#what-a-dev-need-to-share-in-a-post">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    What a Dev need to share in a post
  </a>
  </h3>
<p><em>Bob</em> need to share fragments of the code he writes, some screenshot (images) and a lot of texts. The latest are a simple request because it is the minimum requirements for all the blogging platform.</p>
<p>The code part is the &ldquo;difficult&rdquo; one.</p>
<p>The best situation is if the code is highlighted something like this</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>print(<span style="color:#e6db74">&#34;Hello World!&#34;</span>)</span></span></code></pre></div><p>and the platform need to support all the types of the files <em>Bob</em>&rsquo;s code but we only need the highlight for the languages&hellip;
If <em>Bob</em> needs to blog about <em>Cobol</em> or <em>Pascal</em><sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup></p>
<h3 id="customing-and-theming" class="no-underline ">
  <a href="#customing-and-theming">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Customing and theming
  </a>
  </h3>
<p><em>Bob</em> need to have a solid site/blog with a mobile and a desktop layout (more and more people read blog only with the tablet or the phone) and he need to make no changes or as little as possible for making HIS SITE/BLOG.</p>
<p>He also need a notification system for the followers (newsletters, feed, app with notification, &hellip;) and a SEO integration (analytics, meta, etc&hellip;) for becoming someone on the web.</p>
<p>Less edit he must do for posting better the platform is.</p>
<h3 id="money" class="no-underline ">
  <a href="#money">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Money
  </a>
  </h3>
<p><em>Bob</em> is a developer for money so he doesn&rsquo;t want to spend money so&hellip; The all budget is 10€ (all needed for the domain) so the platform is a good one if it is free but is better if <em>pay</em> <em>Bob</em>.</p>
<p>So he needs a free platform<sup id="fnref:5"><a href="#fn:5" class="footnote-ref" role="doc-noteref">5</a></sup> and some way to make money from the posts (advertising, subscriptions, etc&hellip;)</p>
<p><img  class="center-img u-photo "  src="newspaper.png" alt="NewsPapers"></p>
<h2 id="and-now-the-platforms" class="no-underline ">
  <a href="#and-now-the-platforms">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    And now the platforms
  </a>
  </h2>
<p>Now we know what <em>Bob</em> needs and wants, we find some platforms.</p>
<p>Wordpress, Jekill, Ghost, GoHugo and some other platforms aren&rsquo;t the &ldquo;right one&rdquo; because they aren&rsquo;t a &ldquo;out of the box&rdquo; expirience. You need to customized it and you need to have time for the updating of the platform soo we have SubStack and Medium as the platform.</p>
<h3 id="medium" class="no-underline ">
  <a href="#medium">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Medium
  </a>
  </h3>
<p>The old one, <em>Medium</em> is the platform which is trying to become a blogging space for magazine and journal&rsquo; blogs.
He is online from the 2012 and have all the need for a writer, with tool for automatic sharing, automatic posting and seo tools Medium is a complete platform.</p>
<h3 id="substack" class="no-underline ">
  <a href="#substack">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    SubStack
  </a>
  </h3>
<p>The new one, <em>SubStack</em> is the platform with two faces: one is a blogging space and the other is the mail-list space.
<em>SubStack</em> out of the box way to work is a mail list for your followers, but the site part is not a bad one. It has automatic sharing, automatic posting and a micro-blogging part. But for SEO and promotion it all on you.</p>
<p>It also has one of the better subscribe platform of the web, where you can set some post to <em>pay to read</em> and some <em>free to read</em>.</p>
<h3 id="some-other-considerations" class="no-underline ">
  <a href="#some-other-considerations">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Some other considerations
  </a>
  </h3>
<p>After all this considerations I need to show somethings behind the curtain : Medium has a lot of negative attention[^mediumproblem] because they have a lot of low quality post<sup id="fnref:6"><a href="#fn:6" class="footnote-ref" role="doc-noteref">6</a></sup> and SubStack has its share of problem with the paywall on the newsletters and some problems for the authors.<sup id="fnref:7"><a href="#fn:7" class="footnote-ref" role="doc-noteref">7</a></sup></p>
<p><img  class="center-img u-photo "  src="oz.png" alt="Oz"></p>
<p>In my opinion, if you want to blog about what are you doing, do it and this two platform can be a good starting point for start with your blogging journey but if it become something more you need to invest time in something more tailor to your need and understand what you need and what the platform give you.</p>
<p>If someone make me choose one between Medium and SubStack, I will choose SubStack because I love the idea of having a newsletters but I also feel the limitation of the close platform, bacause I had years and years of blogging on platform I hacked every way.</p>
<p>For example this blog is a GoHugo installation with a <em>out of the box</em> theme but I put so many changing in the code I have something more similar of the Monster of Frankenstein than a well coded theme&hellip;</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Where <em>X</em> is a big but not too big number&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>This is also explained in one of my <a class="a-post interlink-script" href="https://fundor333.com/photos/2025/square-square-square-and-square/"  >old post</a>
&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>This is my blog/webspace so I say <em>my opinion</em> (coder for more than 5 year)&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>Cobol and Pascal are two of the oldest languages and almost every highlighter in a generic blogging platform don&rsquo;t support them, so you need to use a more professional blogging platform and lost time with the custumizations&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:5">
<p>Some function can be hidden by a paywall but if all the <em>needed</em> function are free, the platform is a good one&#160;<a href="#fnref:5" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:6">
<p><a class="a-post interlink-script" href="https://news.ycombinator.com/item?id=24942037"   target="_blank">Please stop writing tutorials/tech articles on Medium&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:6" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:7">
<p><a class="a-post interlink-script" href="https://janefriedman.com/substack-is-both-great-and-terrible-for-authors/"   target="_blank">Substack Is Both Great and Terrible for Authors
&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:7" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/github-action-for-syndication-links/</id><link rel="alternate" href="https://fundor333.com/post/2025/github-action-for-syndication-links/"/><title>Github Action for Syndication Links</title><published>2025-01-23T13:22:54+01:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">How I have syndications'links fill by the machine</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>A lot of time ago I implement the Webmention in my site following a lot of blogpost.</p>
<p>One of them was a bigger ispiration for my implementation<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> and I have some chat with the author of the post over Mastodon for the implementation of the syndications link in a static site<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> and how to implement it.</p>








    
    
        
        
    

    
        <div class="toot">
            <div class="toot-header">
                <a class="toot-profile" href="https://mastodon.social/@fundor333" rel="noopener">
                    <img src="https://files.mastodon.social/accounts/avatars/000/030/873/original/67f41e16a70f9ef6.png"
                         alt="Avatar for @fundor333@mastodon.social"
                         loading="lazy">
                </a>
                <div class="toot-author">
                    <a class="toot-author-name"
                       href="https://mastodon.social/@fundor333"
                       rel="noopener">Fundor333</a>
                    <a class="toot-author-handle"
                       href="https://mastodon.social/@fundor333"
                       rel="noopener">@fundor333@mastodon.social</a>
                </div>
            </div>

            <div class="toot-content"><p><span class="h-card" translate="no"><a href="https://fosstodon.org/@chringel" class="u-url mention">@<span>chringel</span></a></span> How do you fill the syndications&#39; links? By hand?</p></div>

            

            <div class="toot-footer">
                <a href="https://mastodon.social@fundor333/status/108752916197327869"
                   class="toot-date"
                   rel="noopener">10:56 AM · Aug 2, 2022</a>
            </div>
        </div>
    


<p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>








    
    
        
        
    

    
        <div class="toot">
            <div class="toot-header">
                <a class="toot-profile" href="https://fosstodon.org/@chringel" rel="noopener">
                    <img src="https://cdn.fosstodon.org/accounts/avatars/107/558/501/981/999/210/original/ae7e7ef8e5f9c347.png"
                         alt="Avatar for @chringel@fosstodon.org"
                         loading="lazy">
                </a>
                <div class="toot-author">
                    <a class="toot-author-name"
                       href="https://fosstodon.org/@chringel"
                       rel="noopener">Christian 👼</a>
                    <a class="toot-author-handle"
                       href="https://fosstodon.org/@chringel"
                       rel="noopener">@chringel@fosstodon.org</a>
                </div>
            </div>

            <div class="toot-content"><p><span class="h-card" translate="no"><a href="https://mastodon.social/@fundor333" class="u-url mention">@<span>fundor333</span></a></span> Yeah, unfortunately that‘s how I do it.</p><p>1. Publish a post on my blog<br />2. Post the link on Twitter/Mastodon/…<br />3. Update syndication param in front matter and republish</p><p>Haven‘t found another way yet.</p></div>

            

            <div class="toot-footer">
                <a href="https://fosstodon.org@chringel/status/108754642028626230"
                   class="toot-date"
                   rel="noopener">6:15 PM · Aug 2, 2022</a>
            </div>
        </div>
    


<p>After 3 years I find the solution in a post about webmetions!</p>
<h2 id="the-input" class="no-underline ">
  <a href="#the-input">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The input
  </a>
  </h2>
<p>Paul Kinlan wrote an article in the 2019 which flow under my radar and I didn&rsquo;read it untile recently<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>.</p>
<p>In this post he use a Github action to write the webmention into a data folder for his GoHugo implementation. He has a script which download the data and put into file (the name of the file is the hash of the url of the post) which are use to render the webpage interested by the webmention. And all of this into Github Actions&hellip;</p>
<p>So I start thinking about it more and more&hellip;
What can I have the syndications links into a file for url? Like the webmention in this post? I need to read the urls form the social media and other stuff.</p>
<p>But now with X/Twitter in bad shape and Facebook/Meta only good for share photos I only use Mastodon so it is easy read them and write a file for url&hellip;</p>
<p>A implementation I find is this one by Brandon Rozek<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup> that I like in a lot of way but I change it because I don&rsquo;t use Medium&hellip;</p>
<h2 id="the-implementation" class="no-underline ">
  <a href="#the-implementation">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The implementation
  </a>
  </h2>
<p>So I start with the development:</p>
<ol>
<li>I need a file type/data structure standard for the Syndication</li>
<li>I need a script (or more) that find the syndication&rsquo;s links</li>
<li>I need to edit/add to the template some code for the render of it</li>
</ol>
<h3 id="structure-data" class="no-underline ">
  <a href="#structure-data">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Structure data
  </a>
  </h3>
<p>First are the data structure: json, with the name of the file is an hash of the url</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>	<span style="color:#f92672">&#34;syndication&#34;</span>: [
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;https://mastodon.social/@fundor333/113809667070052761&#34;</span>
</span></span><span style="display:flex;"><span>	]
</span></span><span style="display:flex;"><span>}</span></span></code></pre></div><p>For example this is my data for <a class="a-post interlink-script" href="https://fundor333.com/photos/2025/square-square-square-and-square/"  >this post</a>
. I choose Json because I can make check on it and it is a beautiful format for data</p>
<h3 id="the-scraper-script" class="no-underline ">
  <a href="#the-scraper-script">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The Scraper script
  </a>
  </h3>
<p>In this case I find that Mastodon generate a feed for every public profile so I only implementa a reader (class MastodonFinder) which read the feed and save the toots url if find a link to my domain, and a writer class (WriterSyndication) which run all the other class (in this case only the Mastodon one) and write the output as a look-a-like of the json show before.</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> feedparser
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> pathlib <span style="color:#f92672">import</span> Path
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> os
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> json
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> hashlib
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>domain <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;https://fundor333.com&#34;</span>
</span></span><span style="display:flex;"><span>rss_url_mastodon <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;https://mastodon.social/@fundor333.rss&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">clean_slug</span>(slug: str):
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> hashlib<span style="color:#f92672">.</span>md5(
</span></span><span style="display:flex;"><span>        (slug<span style="color:#f92672">.</span>split(<span style="color:#e6db74">&#34;?&#34;</span>)[<span style="color:#ae81ff">0</span>])<span style="color:#f92672">.</span>encode(<span style="color:#e6db74">&#34;utf-8&#34;</span>), usedforsecurity<span style="color:#f92672">=</span><span style="color:#66d9ef">False</span>
</span></span><span style="display:flex;"><span>    )<span style="color:#f92672">.</span>hexdigest()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">MastodonFinder</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">find_urls</span>(self, string):
</span></span><span style="display:flex;"><span>        x <span style="color:#f92672">=</span> string<span style="color:#f92672">.</span>split(<span style="color:#e6db74">&#39;&#34;&#39;</span>)
</span></span><span style="display:flex;"><span>        res <span style="color:#f92672">=</span> []
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">for</span> i <span style="color:#f92672">in</span> x:
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> i<span style="color:#f92672">.</span>startswith(<span style="color:#e6db74">&#34;https:&#34;</span>) <span style="color:#f92672">or</span> i<span style="color:#f92672">.</span>startswith(<span style="color:#e6db74">&#34;http:&#34;</span>):
</span></span><span style="display:flex;"><span>                res<span style="color:#f92672">.</span>append(i)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> res
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">run</span>(self, rss_url: str, domain: str, output: dict):
</span></span><span style="display:flex;"><span>        feed <span style="color:#f92672">=</span> feedparser<span style="color:#f92672">.</span>parse(rss_url)
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> feed<span style="color:#f92672">.</span>status <span style="color:#f92672">==</span> <span style="color:#ae81ff">200</span>:
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">for</span> entry <span style="color:#f92672">in</span> feed<span style="color:#f92672">.</span>entries:
</span></span><span style="display:flex;"><span>                link <span style="color:#f92672">=</span> entry<span style="color:#f92672">.</span>get(<span style="color:#e6db74">&#34;link&#34;</span>)
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">for</span> e <span style="color:#f92672">in</span> self<span style="color:#f92672">.</span>find_urls(entry<span style="color:#f92672">.</span>get(<span style="color:#e6db74">&#34;description&#34;</span>)):
</span></span><span style="display:flex;"><span>                    <span style="color:#66d9ef">if</span> domain <span style="color:#f92672">in</span> e:
</span></span><span style="display:flex;"><span>                        e <span style="color:#f92672">=</span> clean_slug(e)
</span></span><span style="display:flex;"><span>                        <span style="color:#66d9ef">if</span> output<span style="color:#f92672">.</span>get(e, <span style="color:#66d9ef">False</span>):
</span></span><span style="display:flex;"><span>                            output[e]<span style="color:#f92672">.</span>append(link)
</span></span><span style="display:flex;"><span>                        <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span>                            output[e] <span style="color:#f92672">=</span> [link<span style="color:#f92672">.</span>strip()]
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">else</span>:
</span></span><span style="display:flex;"><span>            print(<span style="color:#e6db74">&#34;Failed to get RSS feed. Status code:&#34;</span>, feed<span style="color:#f92672">.</span>status)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">class</span> <span style="color:#a6e22e">WriterSyndication</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">__init__</span>(self, rss_url_mastodon: str, domain: str):
</span></span><span style="display:flex;"><span>        self<span style="color:#f92672">.</span>output <span style="color:#f92672">=</span> {}
</span></span><span style="display:flex;"><span>        self<span style="color:#f92672">.</span>rss_url_mastodon <span style="color:#f92672">=</span> rss_url_mastodon
</span></span><span style="display:flex;"><span>        self<span style="color:#f92672">.</span>domain <span style="color:#f92672">=</span> domain
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">data_gathering</span>(self):
</span></span><span style="display:flex;"><span>        m <span style="color:#f92672">=</span> MastodonFinder()
</span></span><span style="display:flex;"><span>        m<span style="color:#f92672">.</span>run(self<span style="color:#f92672">.</span>rss_url_mastodon, self<span style="color:#f92672">.</span>domain, self<span style="color:#f92672">.</span>output)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">write</span>(self):
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">for</span> key <span style="color:#f92672">in</span> self<span style="color:#f92672">.</span>output<span style="color:#f92672">.</span>keys():
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>            path_folder <span style="color:#f92672">=</span> os<span style="color:#f92672">.</span>path<span style="color:#f92672">.</span>join(<span style="color:#e6db74">&#34;data&#34;</span>, <span style="color:#e6db74">&#34;syndication&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>            Path(path_folder)<span style="color:#f92672">.</span>mkdir(parents<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>, exist_ok<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)
</span></span><span style="display:flex;"><span>            path_file <span style="color:#f92672">=</span> os<span style="color:#f92672">.</span>path<span style="color:#f92672">.</span>join(path_folder, key)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">with</span> open(path_file <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;.json&#34;</span>, <span style="color:#e6db74">&#34;w&#34;</span>) <span style="color:#66d9ef">as</span> fp:
</span></span><span style="display:flex;"><span>                json<span style="color:#f92672">.</span>dump({<span style="color:#e6db74">&#34;syndication&#34;</span>: self<span style="color:#f92672">.</span>output[key]}, fp)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">def</span> <span style="color:#a6e22e">run</span>(self):
</span></span><span style="display:flex;"><span>        self<span style="color:#f92672">.</span>data_gathering()
</span></span><span style="display:flex;"><span>        self<span style="color:#f92672">.</span>write()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>w <span style="color:#f92672">=</span> WriterSyndication(rss_url_mastodon, domain)
</span></span><span style="display:flex;"><span>w<span style="color:#f92672">.</span>run()</span></span></code></pre></div><p>I wrote in this way because I can change the readers or add new one but all the rest of the code remain the same.</p>
<h4 id="todo-one-bug" class="no-underline ">
  <a href="#todo-one-bug">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    TODO one bug
  </a>
  </h4>
<p>Only thing is I need to implement some code for reading all the old file and add to them and not create a new data file if there is an old one.</p>
<h3 id="the-github-action" class="no-underline ">
  <a href="#the-github-action">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The GitHub Action
  </a>
  </h3>
<p>I run it as a Github Action with this parameters.</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">name</span>: <span style="color:#ae81ff">Syndication Link</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">on</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">schedule</span>:
</span></span><span style="display:flex;"><span>    - <span style="color:#f92672">cron</span>: <span style="color:#e6db74">&#34;0 */2 * * *&#34;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">workflow_dispatch</span>:
</span></span><span style="display:flex;"><span><span style="color:#f92672">jobs</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">webmentions</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">runs-on</span>: <span style="color:#ae81ff">ubuntu-latest</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">steps</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Check out repository</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">uses</span>: <span style="color:#ae81ff">actions/checkout@master</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Set up Python</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">uses</span>: <span style="color:#ae81ff">actions/setup-python@v5</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">with</span>:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">python-version</span>: <span style="color:#e6db74">&#34;3.13&#34;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">cache</span>: <span style="color:#e6db74">&#34;pip&#34;</span> <span style="color:#75715e"># caching pip dependencies</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Install Pip dependencies</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">run</span>: <span style="color:#ae81ff">pip install -r requirements.txt</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Fetch Syndication</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">run</span>: <span style="color:#ae81ff">python ./action_script/syndication-collector.py</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      - <span style="color:#f92672">name</span>: <span style="color:#ae81ff">Commit to repository</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">env</span>:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">GITHUB_TOKEN</span>: <span style="color:#ae81ff">${{ secrets.TOKEN }}</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">COMMIT_MSG</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">            👾Fetch webmentions
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">            skip-checks: true</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">run</span>: |<span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          git config user.email &#34;git@fundor333.com&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          git config user.name &#34;fundor333&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          git remote set-url origin https://x-access-token:${GITHUB_TOKEN}@github.com/fundor333/fundor333.github.io.git
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          git checkout main
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          git add .
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">          git diff --quiet &amp;&amp; git diff --staged --quiet || (git commit -m &#34;${COMMIT_MSG}&#34;; git push origin main)</span></span></span></code></pre></div><p>I always put &ldquo;workflow_dispatch&rdquo; as one of the running condiction for having a manual button for running it.</p>
<h3 id="the-template" class="no-underline ">
  <a href="#the-template">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The template
  </a>
  </h3>
<p>This is the template fragment I use to show the syndication of one of the post.
It return a single line of text with all the link of the syndication label as the host of the service (as if it is a mastodon.social/xxxx/xxxx link, the label will be mastodon.social).</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go-html-template" data-lang="go-html-template"><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$urlized</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">.Page.Permalink</span> <span style="color:#f92672">|</span> <span style="color:#a6e22e">md5</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#66d9ef">if</span> <span style="color:#66d9ef">index</span> <span style="color:#a6e22e">.Site.Data.syndication</span> <span style="color:#a6e22e">$urlized</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">hr</span>&gt;
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">br</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">div</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;syndication&#34;</span>&gt;
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">i</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;fas fa-link&#34;</span>&gt;&lt;/<span style="color:#f92672">i</span>&gt;
</span></span><span style="display:flex;"><span>      This post was also syndicated to:
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">{{</span> <span style="color:#a6e22e">$data</span><span style="color:#f92672">:=</span>  <span style="color:#66d9ef">index</span> <span style="color:#a6e22e">.Site.Data.syndication</span> <span style="color:#a6e22e">$urlized</span>  <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">{{</span> <span style="color:#a6e22e">$data</span><span style="color:#f92672">:=</span> <span style="color:#a6e22e">$data</span><span style="color:#a6e22e">.syndication</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">{{</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">$index</span><span style="color:#f92672">,</span> <span style="color:#a6e22e">$url</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">$data</span><span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{-</span> <span style="color:#a6e22e">$parsed_url</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">urls</span><span style="color:#a6e22e">.Parse</span> <span style="color:#a6e22e">$url</span> <span style="color:#75715e">-}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{-</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">$index</span> <span style="color:#75715e">}}</span>, <span style="color:#75715e">{{-</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">a</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;u-syndication&#34;</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$url</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span> <span style="color:#a6e22e">rel</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;syndication&#34;</span>&gt;<span style="color:#75715e">{{</span> <span style="color:#a6e22e">$parsed_url</span><span style="color:#a6e22e">.Host</span> <span style="color:#75715e">}}</span>&lt;/<span style="color:#f92672">a</span>&gt;
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>  &lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">br</span>&gt;
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span></span></span></code></pre></div><p>I also add the microformat2 tags because all my site has them.</p>
<h2 id="conclusion" class="no-underline ">
  <a href="#conclusion">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Conclusion
  </a>
  </h2>
<p>I love this way and I am happy because I resolve a problem I had with my blog for 3 years</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a class="a-post interlink-script" href="https://chringel.dev/2022/07/indiewebify-me-and-dont-forget-my-webmentions/"   target="_blank">Indiewebify me! And don&rsquo;t forget my webmentions!&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p><a class="a-post interlink-script" href="https://fosstodon.org/@chringel/108754642028626230"   target="_blank">dev with the same problem&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p><a class="a-post interlink-script" href="https://paul.kinlan.me/using-web-mentions-in-a-static-sitehugo/"   target="_blank">Using Web Mentions in a static site (Hugo)&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p><a class="a-post interlink-script" href="https://brandonrozek.com/blog/syndicating-hugo-to-medium/"   target="_blank">Syndicating Hugo Posts to Medium&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/this-is-why-instagram-ruin-itself/</id><link rel="alternate" href="https://fundor333.com/post/2025/this-is-why-instagram-ruin-itself/"/><title>This Is Why Instagram Ruin Itself</title><published>2025-01-21T12:42:05+01:00</published><updated>2026-03-08T23:58:29+00:00</updated><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>Instagram is a social network based on images and more recently on short format video (TikTok style) called stories.
But the base concept of Instagram was allways the images first and from the start Instagram&rsquo; photos were squared.</p>
<h2 id="first-problem" class="no-underline ">
  <a href="#first-problem">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    First problem
  </a>
  </h2>
<p>After some time Instagram adds other size and format of image<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> but the profile grid was based on square image.</p>
<p>With this sizing some of the more creative instagram user create design base on the grid of image for making multiple post making a unique photo.</p>
<p>This trend continue with the creation of some app which create the posts&rsquo; images from one single image</p>
<p><img  class="center-img u-photo "  src="grid.jpg" alt="Grid single photo"></p>
<p>And now Instagram has portrait profile grid photo, breaking a lot of profile.
All of this because:</p>
<blockquote>
<p>4:5 is the best ratio for video</p>
<p>Official Instagram Storie about the update</p>
</blockquote>
<p><img  class="center-img u-photo "  src="insta_screen.jpeg" alt="Insta screen"></p>
<h2 id="second-problem" class="no-underline ">
  <a href="#second-problem">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Second problem
  </a>
  </h2>
<p>Meta now has community note not fact checking<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>.
So if i post a photo of my cat flying and I have a big community, I can say in the community note</p>
<blockquote>
<p>Cat can fly on Friday Afternoon but only when Mars is in the Fishes</p>
<p>by Community Note</p>
</blockquote>
<p>Why????</p>
<h2 id="third-problem" class="no-underline ">
  <a href="#third-problem">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Third problem
  </a>
  </h2>
<p>Instagram is pushing videos/reals every time they can. They want to be TikTok but they don&rsquo;t find the right way to do it&hellip;</p>
<p>I don&rsquo;t find the Instagram reals so interesting as the TikTok video so, if I want to see video I go to TikTok. If I want to see photo I go to Instagram</p>
<h2 id="conclusion-without-a-solution" class="no-underline ">
  <a href="#conclusion-without-a-solution">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Conclusion without a solution
  </a>
  </h2>
<p>All of this and the &ldquo;success&rdquo; of PiXelfed<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> Instagram is loosing his apeal and more and more user aren&rsquo;t satisfied with the new &ldquo;feature&rdquo; they are implementing.</p>
<p>I know it isn&rsquo;t a solution but more and more if we want to become indipendent from the social network you need to have a blog with our domain so you have the control of your internet&rsquo;s presence</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Original announcment <a class="a-post interlink-script" href="https://about.instagram.com/blog/announcements/introducing-landscape-and-portrait-formats-on-instagram"   target="_blank">Introducing Landscape and Portrait Formats on Instagram&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p><a class="a-post interlink-script" href="https://about.fb.com/news/2025/01/meta-more-speech-fewer-mistakes/"   target="_blank">Meta now has community note not fact check&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p><a class="a-post interlink-script" href="https://pixelfed.social/i/web"   target="_blank">Social network&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 based on <a class="a-post interlink-script" href="https://en.wikipedia.org/wiki/ActivityPub"   target="_blank">ActivityPub protocol&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/my-zsh-command-history/</id><link rel="alternate" href="https://fundor333.com/post/2025/my-zsh-command-history/"/><title>My Zsh Command History</title><published>2025-01-17T11:47:42+01:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">And I print my ZSH History</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>For social pression of some blogger I follow (<a class="a-post interlink-script" href="https://www.andreagrandi.it/posts/my-zsh-history/"   target="_blank">Andrea Grandi&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
,<a class="a-post interlink-script" href="https://nicolaiarocci.com/my-most-used-command-line-commands/"   target="_blank">Nicola Iarocci&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
, <a class="a-post interlink-script" href="https://www.chrisdeluca.me/2024/12/31/my-cli-wrapped-most-used.html"   target="_blank">Chris DeLuca&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 ) I follow with the history of my terminal (ZSH)</p>
<ul>
<li>90 git</li>
<li>49</li>
<li>38 open</li>
<li>34 poetry</li>
<li>27 make</li>
<li>26 hugo</li>
<li>26 brew</li>
<li>24 cd</li>
<li>18 npm</li>
<li>14 pipenv</li>
</ul>
<p>As a dev the first command is <em>git</em>&hellip; The second command is a bad habits I have&hellip; Spam new line in the terminal&hellip;
I don&rsquo;t find <em>ls</em> and I find it strange&hellip;</p>
<p>Here the command I used</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>history | awk <span style="color:#e6db74">&#39;{print $1}&#39;</span> | sort | uniq --count | sort --numeric-sort --reverse | head -10</span></span></code></pre></div>]]></content></entry><entry><id>tag:fundor333.com,2025:/post/2025/add-photo-page-in-your-hugo-site/</id><link rel="alternate" href="https://fundor333.com/post/2025/add-photo-page-in-your-hugo-site/"/><title>Add Photo Page in your Hugo Site</title><published>2025-01-16T12:49:32+01:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">Some time ago I add a new post type to my blog: photography</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<p>A lot of time ago I was an active user of DevianArt<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> where I share my photos.</p>
<p>One of the things I loved of the site are the meta-data under the photo.
If you share any digital media with metadata, the site show them (<a class="a-post interlink-script" href="https://www.deviantart.com/fundor333/art/Venice-light-1071838909"   target="_blank">example&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
) and because of them I learn something of photography.</p>
<p>But now <a class="a-post interlink-script" href="https://micro.fundor333.com/2025/01/15/do-we-need-all-this/"   target="_blank">DeviantArt is a zombie&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 and Instagram is not in a good place so I want to build my own photo space.</p>
<h2 id="searching-for-theme" class="no-underline ">
  <a href="#searching-for-theme">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Searching for Theme
  </a>
  </h2>
<p>So I search something like a GoHugo Theme with photo gallery and single page info.
Every theme I found with this support I didn&rsquo;t like it.</p>
<p>One has the gallery but not the single page, one was only gallery no posts, one was single photo or video&hellip; So I change my mind and start reading the doc for Gohugo and some article find on google about GoHugo and photos&hellip;</p>
<h2 id="the-solution" class="no-underline ">
  <a href="#the-solution">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The Solution
  </a>
  </h2>
<p>Searching I find an article about EXIF data show under a photo in a GoHugo site<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> so I search for the code for this and I found a second blog post with the implementation for a gallery (a list view for GoHugo) and a render for show the meta data for every photos connect with the new type of post<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup></p>
<p>So I recreate something I liked with the data show but now I am searching for some icons to put near the value, likely the standard icons which you can find in your camera, because it is easy to read and understand.
<img  class="center-img u-photo "  src="result.png" alt="Result of the single page"></p>
<h2 id="some-code" class="no-underline ">
  <a href="#some-code">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Some code
  </a>
  </h2>
<p>In my case I don&rsquo;t need the list view so I don&rsquo;t have a custom code for that. I only have a custom type of content and a template.</p>
<p>So this is the markdown for the <a class="a-post interlink-script" href="https://fundor333.com/photos/2024/near-indiana-johns-library/"  >post</a>
 of the screenshot</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-markdown" data-lang="markdown"><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span>title: &#34;Near Indiana Johns Library&#34;
</span></span><span style="display:flex;"><span>date: 2024-08-30T12:43:56+02:00
</span></span><span style="display:flex;"><span>description: &#34;Sometime in Venice you need to pass under an house. This is one of them&#34;
</span></span><span style="display:flex;"><span>images: [&#39;DSCF0070.jpg&#39;]
</span></span><span style="display:flex;"><span>resources:
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> title: &#34;Near Indiana Johns Library&#34;
</span></span><span style="display:flex;"><span>  src: &#39;DSCF0070.jpg&#39;
</span></span><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Heavily edited with the IA from Lightroom for cleaning, I love this photo but if you print in big format can have problems...
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>I need to work more on the night setting for having less editing.</span></span></code></pre></div><p>In the header of the markdown you need to have all the image you want to render in the page in the variabile <em>images</em> so GoHugo find them and work with them.</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go-html-template" data-lang="go-html-template"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#a6e22e">.Resources.ByType</span> <span style="color:#e6db74">&#34;image&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">{{</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">.</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">{{</span> <span style="color:#a6e22e">$image</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">.Fit</span> <span style="color:#e6db74">&#34;1024x1024&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">figure</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">img</span> <span style="color:#a6e22e">loading</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;lazy&#34;</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$image</span><span style="color:#a6e22e">.RelPermalink</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span> <span style="color:#a6e22e">width</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$image</span><span style="color:#a6e22e">.Width</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span> <span style="color:#a6e22e">height</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$image</span><span style="color:#a6e22e">.Height</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span> <span style="color:#a6e22e">alt</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$.Description</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">figcaption</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;figure-caption&#34;</span>&gt;<span style="color:#75715e">{{</span> <span style="color:#a6e22e">$.Description</span> <span style="color:#75715e">}}</span> - &lt;<span style="color:#f92672">a</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$.Site.BaseURL</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span>&gt;<span style="color:#75715e">{{</span><span style="color:#a6e22e">$.Site.Params.Author.name</span> <span style="color:#75715e">}}</span>&lt;/<span style="color:#f92672">a</span>&gt;&lt;/<span style="color:#f92672">figcaption</span>&gt;
</span></span><span style="display:flex;"><span>      &lt;/<span style="color:#f92672">figure</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#a6e22e">.Exif</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">table</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#a6e22e">$image</span><span style="color:#a6e22e">.Title</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span> <span style="color:#a6e22e">scope</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;col&#34;</span>&gt;Title&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;<span style="color:#75715e">{{</span> <span style="color:#a6e22e">.</span> <span style="color:#75715e">}}</span>&lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#a6e22e">.Date</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span> <span style="color:#a6e22e">scope</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;col&#34;</span>&gt;Date&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;<span style="color:#75715e">{{</span> <span style="color:#a6e22e">.</span> <span style="color:#75715e">}}</span>&lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">isset</span> <span style="color:#a6e22e">.Tags</span> <span style="color:#e6db74">&#34;Model&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span>&gt;Camera&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;<span style="color:#75715e">{{</span> <span style="color:#a6e22e">.Tags.Model</span> <span style="color:#75715e">}}</span>&lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">isset</span> <span style="color:#a6e22e">.Tags</span> <span style="color:#e6db74">&#34;LensModel&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span>&gt;Lens&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;<span style="color:#75715e">{{</span> <span style="color:#a6e22e">.Tags.LensModel</span> <span style="color:#75715e">}}</span>&lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">isset</span> <span style="color:#a6e22e">.Tags</span> <span style="color:#e6db74">&#34;ExposureTime&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span>&gt;Exposure Time&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;<span style="color:#75715e">{{</span> <span style="color:#a6e22e">.Tags.ExposureTime</span> <span style="color:#75715e">}}</span>&lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">isset</span> <span style="color:#a6e22e">.Tags</span> <span style="color:#e6db74">&#34;FNumber&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span>&gt;F Number&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;<span style="color:#75715e">{{</span> <span style="color:#a6e22e">.Tags.FNumber</span> <span style="color:#75715e">}}</span>&lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">isset</span> <span style="color:#a6e22e">.Tags</span> <span style="color:#e6db74">&#34;ISOSpeedRatings&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span>&gt;ISO&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;<span style="color:#75715e">{{</span> <span style="color:#a6e22e">.Tags.ISOSpeedRatings</span> <span style="color:#75715e">}}</span>&lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">isset</span> <span style="color:#a6e22e">.Tags</span> <span style="color:#e6db74">&#34;FocalLength&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span>&gt;Focal Length&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;<span style="color:#75715e">{{</span> <span style="color:#a6e22e">.Tags.FocalLength</span> <span style="color:#75715e">}}</span>&lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">isset</span> <span style="color:#a6e22e">.Tags</span> <span style="color:#e6db74">&#34;ExposureMode&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span>&gt;Exposure Mode&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.ExposureMode</span> <span style="color:#a6e22e">1</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>Manual<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.ExposureMode</span> <span style="color:#a6e22e">0</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>Auto<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>          &lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">isset</span> <span style="color:#a6e22e">.Tags</span> <span style="color:#e6db74">&#34;ExposureProgram&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span>&gt;Exposure Program&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.WhiteBalance</span> <span style="color:#a6e22e">1</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>Manual<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.WhiteBalance</span> <span style="color:#a6e22e">0</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>Auto<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>          &lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#a6e22e">.Tags.ExposureBiasValue</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span>&gt;Exposure Compensation&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;<span style="color:#75715e">{{</span> <span style="color:#a6e22e">.</span> <span style="color:#75715e">}}</span>&lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">isset</span> <span style="color:#a6e22e">.Tags</span> <span style="color:#e6db74">&#34;WhiteBalance&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span>&gt;White Balance&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.WhiteBalance</span> <span style="color:#a6e22e">1</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>Manual<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.WhiteBalance</span> <span style="color:#a6e22e">0</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>Auto<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>          &lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">isset</span> <span style="color:#a6e22e">.Tags</span> <span style="color:#e6db74">&#34;MeteringMode&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>        &lt;<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">th</span>&gt;Metering Mode&lt;/<span style="color:#f92672">th</span>&gt;
</span></span><span style="display:flex;"><span>          &lt;<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.MeteringMode</span> <span style="color:#a6e22e">0</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>Unknown<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.MeteringMode</span> <span style="color:#a6e22e">1</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>Average<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.MeteringMode</span> <span style="color:#a6e22e">2</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>Center Weighted Average<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.MeteringMode</span> <span style="color:#a6e22e">3</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>Spot<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.MeteringMode</span> <span style="color:#a6e22e">4</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>MultiSpot<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.MeteringMode</span> <span style="color:#a6e22e">5</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>Pattern<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.MeteringMode</span> <span style="color:#a6e22e">6</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>Partial<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">{{</span> <span style="color:#66d9ef">with</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">.Tags.MeteringMode</span> <span style="color:#a6e22e">255</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>other<span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>          &lt;/<span style="color:#f92672">td</span>&gt;
</span></span><span style="display:flex;"><span>        &lt;/<span style="color:#f92672">tr</span>&gt;
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>      &lt;/<span style="color:#f92672">table</span>&gt;
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">hr</span>&gt;
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">br</span>&gt;
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  &lt;<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">{{-</span> <span style="color:#a6e22e">.Content</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>  &lt;/<span style="color:#f92672">div</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">div</span>&gt;</span></span></code></pre></div><p>In this template the first thing we do is find all resources which are image and render with a loop.
After render the image in a <em>figure</em> tag we search the file for metadata EXIF.
All the value EXIF we find we show them. Some are inside a &ldquo;switch case&rdquo; because we need something more human readible for some of them.</p>
<p>If you want to see this code in action you can browser my site in the <a class="a-post interlink-script" href="https://fundor333.com/photos/"  >Photography area</a>
 where I use the same list view for the post but this code you can find used on the single photos post.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>A social media site for artists.  <a class="a-post interlink-script" href="https://fundor333.deviantart.com"   target="_blank">Here&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
 is my old profile&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p><a class="a-post interlink-script" href="https://shom.dev/posts/20220128_hugo-photos-with-exif-data/"   target="_blank">Hugo photos with EXIF data&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p><a class="a-post interlink-script" href="https://billglover.me/2023/11/07/creating-a-photography-gallery-with-hugo/"   target="_blank">Creating a Photography Gallery with Hugo&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content></entry><entry><id>tag:fundor333.com,2024:/post/2024/new-render-image-for-hugo/</id><link rel="alternate" href="https://fundor333.com/post/2024/new-render-image-for-hugo/"/><title>New Render Image For Hugo</title><published>2024-07-28T11:37:47+02:00</published><updated>2026-03-08T23:58:29+00:00</updated><summary type="text">The new way to elaborate image for the site generation of the site with Hugo Module</summary><content type="html" xml:base="https://fundor333.com/" xml:lang="en">
<![CDATA[<h2 id="the-story-so-far" class="no-underline ">
  <a href="#the-story-so-far">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    The story so far
  </a>
  </h2>
<p>Some time ago I wrote a post about <em>lazy loading</em> and <em>WebP</em> in <em>Hugo</em> <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> and how I implemented it.</p>
<p>When you add image in your Hugo&rsquo;s site you also launch some script for some image optimization.
Some problems come from the custom script for the build, were you need to have other code install in your machine or wherever you compile your static site.</p>
<p>It was a good implementation and a fast one but some time after I find a better way to implement better way to serve img in a static site, so I wrote a new article <sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> where I describe the implementation with a &ldquo;Hugo&rsquo;s way&rdquo; with a internal pipeline.</p>
<p>In this implementation I combine as find in a blog post <sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> the <em>srv</em> html tag <sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup> in the <em>picture</em> tag <sup id="fnref:5"><a href="#fn:5" class="footnote-ref" role="doc-noteref">5</a></sup> without the Avif format file<sup id="fnref:6"><a href="#fn:6" class="footnote-ref" role="doc-noteref">6</a></sup></p>
<p>I don&rsquo;t like this way because it is inside the theme. I want to have this function like something I can import in any of my Hugo projects without copy and pasting the same code any time.</p>
<p>So I search for something like a package for Hugo so I find the <a class="a-post interlink-script" href="https://gohugo.io/hugo-modules/"   target="_blank">Hugo Module&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
</p>
<h2 id="gohugo-module" class="no-underline ">
  <a href="#gohugo-module">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    GoHugo Module
  </a>
  </h2>
<p><em>Hugo</em> is write in <em>GoLang</em> so the dev implement a way to use a <em>golang module</em> as add-on for your <em>Hugo</em> site.</p>
<p>In my module <a class="a-post interlink-script" href="https://github.com/fundor333/macia-image"   target="_blank">Macia Image&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
<sup id="fnref:7"><a href="#fn:7" class="footnote-ref" role="doc-noteref">7</a></sup> I implemented a &lsquo;partial theme&rsquo; which the only think it does is optimize the image of the posts like the one done for the second post <sup id="fnref1:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>
<h3 id="code" class="no-underline ">
  <a href="#code">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i><i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    Code
  </a>
  </h3>
<p>So this is my code form the path <em><strong>layouts/_default/_markup/render-image.html</strong></em> in the theme from the old way <sup id="fnref2:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup> but now it is at the new path of the module <em><strong>layouts/_default/_markup/render-image.html</strong></em> where I build the images <strong>INSIDE</strong> the post.</p>

<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go-html-template" data-lang="go-html-template"><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{/* Original code from: https://laurakalbag.com/processing-responsive-images-with-hugo/   */}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{/* Just modified a bit to work with render_image hook and output webp images   */}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{/* get file that matches the filename as specified as src=&#34;&#34;  */}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$src</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">.Page.Resources.GetMatch</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">printf</span> <span style="color:#e6db74">&#34;%s&#34;</span> <span style="color:#f92672">(</span><span style="color:#a6e22e">.Destination</span> <span style="color:#f92672">|</span> <span style="color:#a6e22e">safeURL</span><span style="color:#f92672">))</span>  <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$alt</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">.PlainText</span> <span style="color:#f92672">|</span> <span style="color:#a6e22e">safeHTML</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{/* So for posts that aren&#39;t setup in the page bundles, it doesn&#39;t fail  */}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">$src</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$format</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">cond</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">eq</span> <span style="color:#a6e22e">$src</span><span style="color:#a6e22e">.MediaType.SubType</span> <span style="color:#e6db74">&#34;gif&#34;</span><span style="color:#f92672">)</span> <span style="color:#e6db74">&#34;&#34;</span> <span style="color:#e6db74">&#34;webp&#34;</span> <span style="color:#75715e">-}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$xs</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">.Page.Site.Params.maciaimage.tiny</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$s</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">.Page.Site.Params.maciaimage.small</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$m</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">.Page.Site.Params.maciaimage.medium</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$l</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">.Page.Site.Params.maciaimage.large</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$tinyw</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">default</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">printf</span> <span style="color:#e6db74">&#34;%s %s&#34;</span> <span style="color:#a6e22e">$xs</span> <span style="color:#a6e22e">$format</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$smallw</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">default</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">printf</span> <span style="color:#e6db74">&#34;%s %s&#34;</span> <span style="color:#a6e22e">$s</span> <span style="color:#a6e22e">$format</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$mediumw</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">default</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">printf</span> <span style="color:#e6db74">&#34;%s %s&#34;</span> <span style="color:#a6e22e">$m</span> <span style="color:#a6e22e">$format</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$largew</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">default</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">printf</span> <span style="color:#e6db74">&#34;%s %s&#34;</span> <span style="color:#a6e22e">$l</span> <span style="color:#a6e22e">$format</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{/* resize the src image to the given sizes */}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{/* We create a a temp scratch because it`s not available in this context */}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$data</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">newScratch</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$data</span><span style="color:#a6e22e">.Set</span> <span style="color:#e6db74">&#34;tiny&#34;</span> <span style="color:#f92672">(</span><span style="color:#a6e22e">$src</span><span style="color:#a6e22e">.Resize</span> <span style="color:#a6e22e">$tinyw</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$data</span><span style="color:#a6e22e">.Set</span> <span style="color:#e6db74">&#34;small&#34;</span> <span style="color:#f92672">(</span><span style="color:#a6e22e">$src</span><span style="color:#a6e22e">.Resize</span> <span style="color:#a6e22e">$smallw</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$data</span><span style="color:#a6e22e">.Set</span> <span style="color:#e6db74">&#34;medium&#34;</span> <span style="color:#f92672">(</span><span style="color:#a6e22e">$src</span><span style="color:#a6e22e">.Resize</span> <span style="color:#a6e22e">$mediumw</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$data</span><span style="color:#a6e22e">.Set</span> <span style="color:#e6db74">&#34;large&#34;</span> <span style="color:#f92672">(</span><span style="color:#a6e22e">$src</span><span style="color:#a6e22e">.Resize</span> <span style="color:#a6e22e">$largew</span><span style="color:#f92672">)</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{/* add the processed images to the scratch */}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$tiny</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">$data</span><span style="color:#a6e22e">.Get</span> <span style="color:#e6db74">&#34;tiny&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$small</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">$data</span><span style="color:#a6e22e">.Get</span> <span style="color:#e6db74">&#34;small&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$medium</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">$data</span><span style="color:#a6e22e">.Get</span> <span style="color:#e6db74">&#34;medium&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$large</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">$data</span><span style="color:#a6e22e">.Get</span> <span style="color:#e6db74">&#34;large&#34;</span> <span style="color:#75715e">}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">{{/* only use images smaller than or equal to the src (original) image size, as Hugo will upscale small images */}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">a</span> <span style="color:#a6e22e">href</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$src</span><span style="color:#a6e22e">.RelPermalink</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span>&gt;
</span></span><span style="display:flex;"><span>    &lt;<span style="color:#f92672">picture</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">source</span> <span style="color:#a6e22e">media</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;(max-width: 376px)&#34;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#a6e22e">srcset</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span><span style="color:#66d9ef">with</span> <span style="color:#a6e22e">$tiny</span><span style="color:#a6e22e">.RelPermalink</span> <span style="color:#75715e">}}{{</span><span style="color:#a6e22e">.</span><span style="color:#75715e">}}{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">source</span> <span style="color:#a6e22e">media</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;(max-width: 992px)&#34;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#a6e22e">srcset</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span><span style="color:#66d9ef">with</span> <span style="color:#a6e22e">$small</span><span style="color:#a6e22e">.RelPermalink</span> <span style="color:#75715e">}}{{</span><span style="color:#a6e22e">.</span><span style="color:#75715e">}}{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">source</span> <span style="color:#a6e22e">media</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;(max-width: 1400px)&#34;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#a6e22e">srcset</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span><span style="color:#66d9ef">with</span> <span style="color:#a6e22e">$medium</span><span style="color:#a6e22e">.RelPermalink</span> <span style="color:#75715e">}}{{</span><span style="color:#a6e22e">.</span><span style="color:#75715e">}}{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">source</span> <span style="color:#a6e22e">media</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;(min-width: 1600px)&#34;</span>
</span></span><span style="display:flex;"><span>          <span style="color:#a6e22e">srcset</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span><span style="color:#66d9ef">with</span> <span style="color:#a6e22e">$large</span><span style="color:#a6e22e">.RelPermalink</span> <span style="color:#75715e">}}{{</span><span style="color:#a6e22e">.</span><span style="color:#75715e">}}{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      &lt;<span style="color:#f92672">img</span> <span style="color:#a6e22e">alt</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$alt</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span> <span style="color:#a6e22e">title</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$alt</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span> <span style="color:#a6e22e">src</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$src</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span> <span style="color:#a6e22e">loading</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;lazy&#34;</span> <span style="color:#a6e22e">decoding</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;async&#34;</span> <span style="color:#a6e22e">height</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$src</span><span style="color:#a6e22e">.Height</span><span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span> <span style="color:#a6e22e">width</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span> <span style="color:#a6e22e">$src</span><span style="color:#a6e22e">.Width</span> <span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span> <span style="color:#a6e22e">class</span><span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#75715e">{{</span><span style="color:#a6e22e">.Page.Site.Params.maciaimage.imgclass</span><span style="color:#75715e">}}</span><span style="color:#e6db74">&#34;</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    &lt;/<span style="color:#f92672">picture</span>&gt;
</span></span><span style="display:flex;"><span>&lt;/<span style="color:#f92672">a</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">{{/* Since I do image-response class, the only thing that really
</span></span></span><span style="display:flex;"><span><span style="color:#75715e">  matters is the height and width matches the image aspect ratio */}}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">{{</span> <span style="color:#66d9ef">end</span> <span style="color:#75715e">}}</span></span></span></code></pre></div><p>In this code I set some values from the configs of the site so you can customize it in your theme and import it when ever you need it.</p>
<h2 id="nb" class="no-underline ">
  <a href="#nb">
    <i class="fa-whiteboard fa-semibold fa-angle-right"></i>
    NB
  </a>
  </h2>
<p>This code, unlike the old one <sup id="fnref3:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>, support the <em>Gif</em> file format and output only file as <em>WebP</em> and a lot of them.
As you can see in the script, the code generate 4 copy of the original image with 4 different image size (configurable in the config of the site).</p>
<p>When the Hugo&rsquo;s Team add support for <em>Avif</em><sup id="fnref1:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup> I will add it into the module for generate all the image with the config setting which format image will be outputting.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Fundor333 - <a class="a-post interlink-script" href="https://fundor333.com/post/2021/hugo-with-lazy-loading-and-webp/"  >Hugo With Lazy Loading and Webp</a>
&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>Fundor333 - <a class="a-post interlink-script" href="https://fundor333.com/post/2021/webp-and-avif-with-hugo-generator/"  >Generate WebP and AVIF with Hugo</a>
&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref1:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref2:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref3:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>From Bennett Notes - <a class="a-post interlink-script" href="https://www.bennettnotes.com/notesnotes/hugo-responsive-images-with-markdown-render-hook/"   target="_blank">Hugo Responsive Images With Markdown Render Hook&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a>&#160;<a href="#fnref1:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>Mozilla wiki - <a class="a-post interlink-script" href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/srcset"   target="_blank">Src set&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:5">
<p>Mozilla wiki - <a class="a-post interlink-script" href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture"   target="_blank">Tag HTML picture&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:5" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:6">
<p>GitHub issue - <a class="a-post interlink-script" href="https://github.com/gohugoio/hugo/issues/7837"   target="_blank">Add image processing support for AVIF&nbsp;&nbsp;<i class="fa-whiteboard fa-semibold fa-link"></i></a>
&#160;<a href="#fnref:6" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:7">
<p><em>Macia</em> (like the tea) is the name of all my Hugo&rsquo;s module and <em>Image</em> for the scope of the project&#160;<a href="#fnref:7" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content></entry></feed>