افزودن بخش دیدگاه‌ها با ماستودون

ماستودون

از ویکی‌پدیا، دانشنامه آزاد

ماستودون (به انگلیسی: Mastodon) یک نرم‌افزار آزاد و متن‌باز خودمیزبان (خدمات وب) برای ساخت شبکهٔ اجتماعی است که این امکان را به هر شخص می‌دهد تا گره سرور خود را در شبکه میزبانی کند و پایگاه‌های مختلف از کاربران آن در میان سروهای متفاوتی پخش هستند.

این سرورها به صورت شبکه اجتماعی فدرال به هم متصل هستند، که به کاربران خود اجازه می‌دهد با یکدیگر به شکل یکپارچه تعامل داشته باشند. ماستودون عضوی از یک فدراسیون بزرگ‌تر است که به کاربران امکان می‌دهد با دیگر سکوهای آزاد مانند پیرتیوب و فرندیکا که قوانین یکسانی را پشتیبانی می‌کنند تعامل داشته باشند.

افزودن بخش دیدگاه‌ها با ماستودون

یکی از دشواری‌های وبسایت‌ها استاتیک افزودن بخش دیدگاه‌هاست. گزینه‌های گوناگونی برای انجام این کار وجود دارد. یک راهکار ساده استفاده از Disqus است. چون Disqus سنگین است و مقدار زیادی اسکریپت غیرضروری در صفحات بارگزاری می‌کند و مهم‌تر از همه آزاد نیست هرگز گزینه مطلوبی برای من نبود. برای دیدن راهکارهای بیشتر می‌توانید این پست مهدی صادقی را ببینید.

با سپاس از ‪@carl‬ برای نوشتن کد و گزارشی که در این پست نوشته است، از این پس شما می‌توانید با داشتن یک اکانت ماستودون دیدگاه‌های خودتان را برای من بفرستید، و آنچه دیگران نوشته‌اند را هم ببینید.

کد جاوا اسکریپت

چون کد اصلی برای #HUGO نوشته شده بود، من تغییرات اندکی در آن دادم تا با #JEKYLL سازگار شود و آن را در فایل mastodon.html در پوشه _includes قراد دادم:

<div class="page-content">
  <h2>دیدگاه‌ها</h2>
  <p>می‌توانید دیدگاه‌های این پست را در ماستودون و<a class="link" href="https://{{ page.mastodon.host }}/@{{ page.mastodon.username }}/{{ page.mastodon.id }}" target="_blank" rel="noopener noreferrer"> اینجا </a>ببینید. برای نوشتن دیدگاه خود روی لینک زیر کلیک کنید.</p>
  <p><a class="button" href="https://{{ page.mastodon.host }}/@{{ page.mastodon.username }}/{{ page.mastodon.id }}" target="_blank" rel="noopener noreferrer">نوشتن دیدگاه‌</a></p>
  <p></p>
  <p id="mastodon-comments-list"><a id="load-comment" class="button">دیدن دیدگاه‌ها</a></p>
  <div id="comments-wrapper">
    <noscript><p>برای این بخش می‌باید جاوا اسکریپت را فعال کنید، یا <a href="https://{{ page.mastodon.host }}/@{{ page.mastodon.username }}/{{ page.mastodon.id }}" target="_blank" rel="noopener noreferrer">پست اصلی</a> را در ماستودون ببینید</p></noscript>
  </div>
  <script src="/assets/js/purify.min.js"></script>
  <script type="text/javascript">
    function escapeHtml(unsafe) {
      return unsafe
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
    }

    function emojify(input, emojis) {
      let output = input;

      emojis.forEach(emoji => {
        let picture = document.createElement("picture");

        let source = document.createElement("source");
        source.setAttribute("srcset", escapeHtml(emoji.url));
        source.setAttribute("media", "(prefers-reduced-motion: no-preference)");

        let img = document.createElement("img");
        img.className = "emoji";
        img.setAttribute("src", escapeHtml(emoji.static_url));
        img.setAttribute("alt", `:${ emoji.shortcode }:`);
        img.setAttribute("title", `:${ emoji.shortcode }:`);
        img.setAttribute("width", "20");
        img.setAttribute("height", "20");

        picture.appendChild(source);
        picture.appendChild(img);

        output = output.replace(`:${ emoji.shortcode }:`, picture.outerHTML);
      });

      return output;
    }

    function loadcomments() {
      document.getElementById("load-comment").innerHTML = "دریافت دیدگاه‌ها";
      fetch('https://{{ page.mastodon.host }}/api/v1/statuses/{{ page.mastodon.id }}/context')
        .then(function(response) {
          return response.json();
        })
        .then(function(data) {
          let descendants = data['descendants'];
          if(
            descendants &&
            Array.isArray(descendants) &&
            descendants.length > 0
          ) {
            document.getElementById('mastodon-comments-list').innerHTML = "";
            descendants.forEach(function(reply) {
              if( reply.account.display_name.length > 0 ) {
                reply.account.display_name = escapeHtml(reply.account.display_name);
                reply.account.display_name = emojify(reply.account.display_name, reply.account.emojis);
              } else {
                reply.account.display_name = reply.account.username;
              };

              reply.content = emojify(reply.content, reply.emojis);

              reply.created_at = new Date( reply.created_at ).toLocaleString('fa-IR', {
                dateStyle: "long",
                timeStyle: "short",
              });

              let instance = "";
              if( reply.account.acct.includes("@") ) {
                instance = reply.account.acct.split("@")[1];
              } else {
                instance = "{{ page.mastodon.host }}";
              }

              mastodonComment =
                `<div class="mastodon-comment">
                <div class="avatar">
                <img src="${escapeHtml(reply.account.avatar_static)}" height=60 width=60 alt="">
                </div>
                <div class="content">
                <div class="author" title="profile: @${ reply.account.username }@${ instance }">
                <a href="${reply.account.url}" target="_blank" rel="external nofollow">
                <span>${reply.account.display_name}</span>
                <span class="instance">${instance}</span>
                </a>
                </div>
                <div title="دیدن دیدگاه در ${ instance }">
                <a class="date" href="${reply.uri}" target="_blank" rel="external nofollow">
                ${reply.created_at}
                </a>
                </div>
                <div class="mastodon-comment-content">${reply.content}</div> 
                </div>
                </div>`;
              document.getElementById('mastodon-comments-list').appendChild(DOMPurify.sanitize(mastodonComment, {'RETURN_DOM_FRAGMENT': true}));
            });
          } else {
            document.getElementById('mastodon-comments-list').innerHTML = "<p>بدون دیدگاه</p>";
          }
        });
    }
    document.getElementById("load-comment").addEventListener("click", loadcomments);
  </script>
</div>

سپس در layout مربوط به پست‌ها یک شرط افزودم تا هر زمان که در frontmatter پست ‍mastodon وجود داشت، بخش دیدگاه‌ها افزوده شود:

{% if page.mastodon %}
  {% include mastodon.html %}
{% endif %}

و در frontmatter باید mastodon با این ساختار افزوده شود:

mastodon:
  host: mas.to
  username: mz
  id: 105582586560918183

که باید این موارد در آن مشخص گردد:

  • host: آدرس سرور ماستودون
  • username: نام کاربری در ماستودون
  • id: شماره یکتای بوق مربوط به پست

در پایان هم برای نمایش بهتر دیدگاه‌ها از این چند خط CSS استفاده کردم.

اینجا می‌توانید نتیجه نهایی را آزمایش کنید:

دیدگاه‌ها

می‌توانید دیدگاه‌های این پست را در ماستودون و اینجا ببینید. برای نوشتن دیدگاه خود روی لینک زیر کلیک کنید.

نوشتن دیدگاه‌

دیدن دیدگاه‌ها