Как создать свой собственный Taplink с помощью Python и GitHub Pages

от автора

Я случайно наткнулся на статью автора Lucas Neves Pereira под названием «Build your own LinkTree with Go and GitHub Pages«. В статье описано, как создать подобие LinkTree (аналог Taplink) на языке Go и GitHub Pages. Я, как любитель языка Python, решил реализовать проект на этом языке.

king-tri-ton.github.io/pythonpagelink

king-tri-ton.github.io/pythonpagelink

Шаг 1: Подготовка файловой структуры проекта

Первым делом создадим файловую структуру для нашего проекта. Мы организуем наш проект таким образом, чтобы он был легко поддерживаемым и удобным для развертывания на GitHub Pages.

Файловая структура:

/ (root) |-- /docs |   |-- index.html |   |-- /assets |       |-- (файлы стилей, скриптов, иконок и т.д.) |-- config.yml |-- generate_site.py |-- /themes
  • /docs: В этой папке будут храниться сгенерированные HTML-файлы и все необходимые ассеты (изображения, стили, скрипты). Эта папка будет использоваться для развертывания сайта на GitHub Pages.

  • config.yml: Файл конфигурации, который содержит все данные для персонализации сайта.

  • generate_site.py: Скрипт на Python, который будет генерировать сайт на основе данных из config.yml.

  • /themes: Папка с темами для сайта. В нашем случае, здесь хранится единственная тема custom, которая включает в себя шаблон HTML, стили, скрипты и изображения.

Шаг 2: Настройка файла конфигурации (config.yml)

Файл config.yml содержит данные о пользователе и ссылки, которые будут отображаться на сайте. Вот его содержимое:

name: "King Triton" picture: "assets/img/picture.jpg" bio: "Programmer python and php/laravel" meta:   lang: "en"   description: "Programmer python and php/laravel"   title: "King Triton"   author: "King Triton"   siteUrl: "https://king-tri-ton.github.io/pythonpagelink/" links:   - name: "Github"     url: "https://github.com/king-tri-ton"   - name: "Dev.to"     url: "https://dev.to/king_triton"   - name: "Patreon"     url: "https://www.patreon.com/king_triton"   - name: "Telegram"     url: "https://t.me/king_triton"   - name: "Instagram"     url: "https://www.instagram.com/king_tri_ton" theme: "custom" 
  • name: Имя пользователя, которое будет отображаться на сайте.

  • picture: Путь к изображению пользователя.

  • bio: Краткая биография пользователя.

  • meta: Метаинформация сайта (язык, описание, заголовок, автор, URL сайта).

  • links: Список ссылок, которые будут отображаться на сайте. Каждый элемент содержит название и URL.

  • theme: Тема сайта, которую следует использовать.

Шаг 3: Разработка Python-скрипта для генерации сайта (generate_site.py)

Далее мы напишем скрипт на Python, который будет использовать шаблон из темы, данные из config.yml и генерировать готовый HTML-файл.

import os import shutil from jinja2 import Environment, FileSystemLoader import yaml  # Загрузка конфигурации with open('config.yml', 'r') as config_file:     config = yaml.safe_load(config_file)  # Создание выходной директории output_dir = 'docs' os.makedirs(output_dir, exist_ok=True)  # Настройка Jinja2 env = Environment(loader=FileSystemLoader('themes/custom')) template = env.get_template('index.html')  # Генерация HTML файла output_html = template.render(config=config) with open(os.path.join(output_dir, 'index.html'), 'w') as fh:     fh.write(output_html)  # Копирование папки assets в выходной каталог assets_source = os.path.join('themes', config['theme'], 'assets') assets_dest = os.path.join(output_dir, 'assets') if os.path.exists(assets_source):     shutil.copytree(assets_source, assets_dest, dirs_exist_ok=True)  print("Site generated successfully.") 
  • Загрузка конфигурации: Скрипт загружает данные из файла config.yml.

  • Создание выходной директории: Папка docs создается автоматически, если она не существует.

  • Настройка Jinja2: Используется Jinja2 для загрузки шаблона HTML и рендеринга контента.

  • Генерация HTML-файла: Скрипт генерирует файл index.html с использованием данных из конфигурации и сохраняет его в папке docs.

  • Копирование ассетов: Все ассеты (CSS, изображения, скрипты) копируются в папку docs/assets.

Шаг 4: Создание темы и ассетов

Теперь создадим тему, которая будет использоваться для нашего сайта. В папке themes/custom/ должны находиться следующие файлы:

themes/custom/index.html

Это основной HTML-шаблон сайта. Он использует переменные из файла конфигурации.

<!DOCTYPE html> <html lang="{{ config.meta.lang }}"> <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <meta name="description" content="{{ config.meta.description }}">     <title>{{ config.meta.title }}</title>     <meta name="author" content="{{ config.meta.author }}">     <link rel="canonical" href="{{ config.meta.siteUrl }}">     <link rel="icon" type="image/x-icon" href="assets/icons/favicon.ico">     <link rel="stylesheet" href="assets/css/styles.css">     <meta property="og:title" content="{{ config.meta.title }}">     <meta property="og:site_name" content="{{ config.meta.title }}">     <meta property="og:description" content="{{ config.meta.description }}">     <meta property="og:locale" content="{{ config.meta.lang }}">     <meta name="twitter:title" content="{{ config.meta.title }}">     <meta name="twitter:description" content="{{ config.meta.description }}"> </head> <body>     <header>         <img src="{{ config.picture }}" alt="Picture" class="avatar">         <h1>{{ config.name }}</h1>         <small class="bio">{{ config.bio }}</small>     </header>     <main>         <section class="links">             {% for link in config.links %}             <a class="link-item" href="{{ link.url }}" target="_blank" rel="noopener noreferrer">                 <p>{{ link.name }}</p>             </a>             {% endfor %}         </section>     </main>     <footer>         <small>© <span class="year"></span> {{ config.meta.author }}</small>     </footer>     <script src="assets/js/script.js"></script> </body> </html> 

themes/custom/assets/styles.css

Файл CSS для стилизации страницы.

/* CSS Reset */ * {   margin: 0;   padding: 0;   box-sizing: border-box; }  /* Variables */ :root {   --max-width: 600px;   --font-family: 'Inter', sans-serif;   --padding: 1rem;   --header-margin-bottom: 1rem;   --line-height: 2;   --font-size: 16px;    --primary-color-light: #ffffff;   --background-color-light: #f0f0f0;   --text-color-light: #333;   --link-color-light: #1a73e8;   --bio-color-light: #666;    --primary-color-dark: #1e1e1e;   --background-color-dark: #121212;   --text-color-dark: #e0e0e0;   --link-color-dark: #8ab4f8;   --bio-color-dark: #aaa; }  /* Light Theme */ @media (prefers-color-scheme: light) {   :root {     --primary-color: var(--primary-color-light);     --background-color: var(--background-color-light);     --text-color: var(--text-color-light);     --link-color: var(--link-color-light);     --bio-color: var(--bio-color-light);   } }  /* Dark Theme */ @media (prefers-color-scheme: dark) {   :root {     --primary-color: var(--primary-color-dark);     --background-color: var(--background-color-dark);     --text-color: var(--text-color-dark);     --link-color: var(--link-color-dark);     --bio-color: var(--bio-color-dark);   } }  /* Global Styles */ html {   font-family: var(--font-family);   font-size: var(--font-size);   line-height: var(--line-height); }  body {   max-width: var(--max-width);   min-height: 100vh;   margin: 0 auto;   display: flex;   flex-direction: column;   align-items: center;   background-color: var(--background-color);   color: var(--text-color);   padding: var(--padding); }  /* Header Styles */ header {   padding: var(--padding) 0;   margin-bottom: var(--header-margin-bottom);   width: 100%;   display: flex;   flex-direction: column;   justify-content: center;   align-items: center;   text-align: center; }  .avatar {   width: 100px;   height: 100px;   border-radius: 50%;   object-fit: cover;   border: 2px solid var(--primary-color);   box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); }  h1 {   font-size: 24px;   margin-bottom: 0.5rem; }  .bio {   font-size: 14px;   color: var(--bio-color);   margin-bottom: 1rem; }  /* Main Content Styles */ main {   width: 100%;   flex: 1; }  .links {   display: flex;   flex-direction: column;   gap: 1rem;   text-align: center;   overflow-y: auto;   max-height: 400px; }  .link-item {   display: block;   padding: 16px 20px;   text-decoration: none;   color: var(--link-color);   background: var(--primary-color);   border-radius: 12px;   border: 1px solid var(--link-color);   transition: background-color 0.25s, color 0.25s; }  .link-item:hover, .link-item:focus {   background-color: var(--link-color);   color: var(--primary-color); }  .link-item p {   line-height: 1.5;   font-weight: 500; }  /* Footer Styles */ footer {   width: 100%;   text-align: center;   padding: 1rem 0;   font-size: 14px;   gap: 1rem;   display: flex;   justify-content: center;   align-items: center; }  /* ScrollBar */ ::-webkit-scrollbar {   width: 5px; }  ::-webkit-scrollbar-track {   background: transparent; }  ::-webkit-scrollbar-thumb {   background: transparent; }  ::-webkit-scrollbar-thumb:hover {   background: transparent; }

themes/custom/assets/js/script.js

Файл JavaScript для базовых функциональностей.

console.log("scripts loaded");  const yearDate = new Date().getFullYear().toString(); document.querySelector(".year").innerText = yearDate;

themes/custom/assets/img/picture.jpg

Фотография, которая будет использоваться в качестве аватара.

Шаг 5: Генерация сайта

После того как все файлы созданы, запустите скрипт generate_site.py, чтобы сгенерировать сайт:

python generate_site.py

Сайт будет сгенерирован в папке docs.

Шаг 6: Развертывание на GitHub Pages

Развертывание на GitHub Pages

Развертывание на GitHub Pages
  • Создайте новый репозиторий на GitHub.

  • Загрузите все файлы, включая папку docs, в репозиторий.

  • Перейдите в раздел Settings репозитория.

  • В разделе Pages выберите ветку master и папку /docs как источник.

  • Сохраните изменения и подождите, пока GitHub Pages развернет ваш сайт.

Теперь ваш сайт будет доступен по адресу https://[username].github.io/[repository-name]/


Вот и все! Теперь у вас есть собственный сайт в стиле Taplink, созданный на Python и развернутый на GitHub Pages. Вы можешь посмотреть мой готовый результат по адресу https://king-tri-ton.github.io/pythonpagelink/.

Благодарю за внимание!


ссылка на оригинал статьи https://habr.com/ru/articles/839574/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *