Github Repolarının Bilgilerini Eleventy'de Listeleme


yazıldı

3 dakika okuma süresi

Ne zamandır sitede yaptığım projeleri listelemek istiyordum. Artık buradan ulaşılabiliyor.

Bunun için gerçekten birçok yol denedim; hepsi başarısızlıkla sonuçlandı. Nihayetinde, Tanner'ın sitesinin kaynak kodlarında aradığım kodları buldum. (Benim yaklaşımım tam olarak buradaki gibi değildi ama, işe yarıyor sonuçta.)

Kod, Github API'den belirlediğimiz repoların bilgilerini çekiyor ve eleventy-cache-assets yardımıyla belirli bir süre ön belleğe alıyor; böylelikle her değişiklikte tekrardan indirmemiş oluyor. Bu çekilen bilgiler de Eleventy'nin Javascript Veri Dosyası özelliği yardımıyla şablonlarda ulaşılabilir hale geliyor.

İhtiyacımız olan üç şey var; javascript veri dosyası, bu verilerden çektiğimiz bilgileri listelemek için bir şablon ve güzel bir stil dosyası.

Öncelikle gerekli bağımlılık olan eleventy-cache-assets paketini aşağıdaki komutla yüklüyoruz:

yarn add @11ty/eleventy-cache-assets

Javascript Veri Dosyası

Benim kullandığım kod bu şekilde, burada pek bir değişiklik yok olduğu gibi alıp kendi repolarımı ekledim. Bu dosyanın _data klasöründe olması gerekiyor. (eğer başka bir data klasörü belirlemediyseniz.) Ben src/_data/github.js olarak kaydettim.

const Cache = require("@11ty/eleventy-cache-assets");
 
async function fetchData(url) {
  console.log(`Caching: ${url}`);
  try {
    let json = await Cache(url, {
      duration: "2h",
      type: "json",
    });
    return {
      title: json.name,
      desc: json.description,
      stargazers: json.stargazers_count,
      subscribers: json.subscribers_count,
      forks: json.forks_count,
      issues: json.open_issues,
      stargazers_url: json.html_url.concat("/stargazers/"),
      homepage: json.homepage,
      repo_url: json.html_url,
    };
  } catch (e) {
    console.log(`Error caching: ${url}`);
    return {
      title: "A Github Project by TaylanTatli",
      desc: "This project was created by @TaylanTatli",
      stargazers: 0,
      subscribers: 0,
      forks: 0,
      issues: 0,
      stargazers_url: "https://github.com/TaylanTatli",
      homepage: "https://github.com/TaylanTatli",
      repo_url: "https://github.com/TaylanTatli",
    };
  }
}
 
module.exports = async function () {
  try {
    const moon = await fetchData(
      "https://api.github.com/repos/TaylanTatli/Moon"
    );
    const halve = await fetchData(
      "https://api.github.com/repos/TaylanTatli/Halve"
    );
    const ramme = await fetchData(
      "https://api.github.com/repos/TaylanTatli/Ramme"
    );
    const daisy = await fetchData(
      "https://api.github.com/repos/TaylanTatli/Daisy-Pelican-Theme"
    );
    const addToMiniflux = await fetchData(
      "https://api.github.com/repos/TaylanTatli/add-to-miniflux"
    );
    const gearyTray = await fetchData(
      "https://api.github.com/repos/TaylanTatli/geary-tray-icon"
    );
    const inkdropBeraSyntax = await fetchData(
      "https://api.github.com/repos/TaylanTatli/inkdrop-bera-light-syntax-theme"
    );
    const inkdropBeraPreview = await fetchData(
      "https://api.github.com/repos/TaylanTatli/inkdrop-bera-preview-theme"
    );
    const inkdropBeraUI = await fetchData(
      "https://api.github.com/repos/TaylanTatli/inkdrop-bera-light-ui-theme"
    );
    const inkdropMarkText = await fetchData(
      "https://api.github.com/repos/TaylanTatli/inkdrop-mark-text"
    );
    const inkdropDraculaSyntax = await fetchData(
      "https://api.github.com/repos/TaylanTatli/inkdrop-dracula-syntax-theme"
    );
    const inkdropDraculaPreview = await fetchData(
      "https://api.github.com/repos/TaylanTatli/inkdrop-dracula-preview-theme"
    );
    const inkdropDraculaUI = await fetchData(
      "https://api.github.com/repos/TaylanTatli/inkdrop-dracula-dark-ui-theme"
    );
    // return the promise for each project <Promise{ title: ... }>
    return {
      moon,
      halve,
      ramme,
      daisy,
      addToMiniflux,
      gearyTray,
      inkdropBeraSyntax,
      inkdropBeraPreview,
      inkdropBeraUI,
      inkdropMarkText,
      inkdropDraculaSyntax,
      inkdropDraculaPreview,
      inkdropDraculaUI,
    };
  } catch (e) {
    console.log("Error returning multiple projects cached API data");
  }
};

Nunjucks Şablon Dosyası

Orijinal koddan farklı burası çünkü, orijinalinde her değişken tek tek elle girilmiş; ben bunun yerine for döngüsü kullandım. Ayrıca düzeni de bir miktar değiştirdim kendi siteme göre. Ben base.njk şablonuna genişleterek kullanıyorum bu şablonu, kendi düzeninize göre değiştirmeniz gerekebilir.

---
title: "Projeler"
permalink: /projects/
---
{% extends "layouts/base.njk" %}
{% block main %}
<h1 class="projects-title">{{ title }}</h1>
<ul class="projects">
  {% for repo_name, repo in github %}
  <li class="project">
    <div class="project-details">
      <h3 class="project-title">{{ repo.title }}</h3>
      <a class="project-star" href="{{ repo.stargazers_url }}" target="_blank" rel="noreferrer">☆ <span>{{ repo.stargazers }}</span></a>
    </div>
    <p class="project-description">{{ repo.desc }}</p>
    <ul class="project-links">
      {% if repo.homepage %}
      <li><a class="project-link" href="{{ repo.homepage }}" target="_blank" rel="noreferrer" aria-label="View the live demo for {{ repo.title }}">Live demo</a></li>
      {% endif %}
      <li><a class="project-link" href="{{ repo.repo_url }}" target="_blank" rel="noreferrer" aria-label="View the source code for {{ repo.title }}">Source code</a></li>
    </ul>
  </li>
  {% endfor %}
</ul>
{% endblock %}
 

SCSS Stil Dosyası

Orijinale oldukça benzer, sadece kendi düzenime ve sınıf isimlerime göre hazırladım.

.projects {
  list-style: none;
  margin: 0;
  padding: 0;
  &-title {
    margin-bottom: 1rem;
    text-decoration: none;
    font-size: 2rem;
    text-align: center;
  }
}
.project {
  border: 1px solid hsl(39, 24%, 66%);
  border-radius: 0.15rem;
  padding: 0.25rem 0.5rem;
  margin-bottom: 1rem;
  &-details {
    display: flex;
    justify-content: space-between;
    align-items: center;
    h3 {
      margin: 1rem 0 0;
      text-decoration: none;
    }
    a.project-star {
      text-decoration: none;
      color: inherit;
    }
  }
  &-description {
    margin: 0.25rem 0 1rem;
  }
  &-links {
    margin: 1.5rem 0 1rem;
    padding-left: 0;
    list-style: none;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    a {
      text-decoration: none;
      font-size: 0.9rem;
      padding: 0.5rem;
      margin-right: 0.65rem;
      border: 0.05rem solid hsl(39, 24%, 66%);
      border-radius: 0.15rem;
      color: inherit;
    }
  }
}

Sonuç

eleventy-cache-assets, önbelleğe aldığı dosyaları .cache klasöründe saklayacaktır. Bunu .gitignore dosyanıza .cache/ şeklinde eklemeniz mantıklı olacaktır. Sürekli indirmesini istemememizin nedeni, site üzerinde çalışma yaparken her seferinde indirmesine gerek olmamasından kaynaklanıyor ama siteyi yayınlarken her seferinde güncel olan bilgileri çekilmesi daha doğru olur.

Tüm bunlardan sonra elde edeceğimiz görüntü bu:

Proje Listesi

Orijinal Çalışma: