mirror of
https://github.com/10h30/astroplate.git
synced 2026-07-11 10:46:07 +09:00
project setup
This commit is contained in:
+8
-1
@@ -12,7 +12,14 @@ import config from "./src/config/config.json";
|
||||
export default defineConfig({
|
||||
site: config.site.base_url ? config.site.base_url : "http://examplesite.com",
|
||||
base: config.site.base_path ? config.site.base_path : "/",
|
||||
trailingSlash: config.site.trailing_slash ? "always" : "never",
|
||||
trailingSlash: config.site.trailing_slash ? "always" : "ignore",
|
||||
i18n: {
|
||||
locales: ["en", "fr", "ar"],
|
||||
defaultLocale: "en",
|
||||
routing: {
|
||||
prefixDefaultLocale: false,
|
||||
},
|
||||
},
|
||||
image: {
|
||||
service: squooshImageService(),
|
||||
},
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "astroplate",
|
||||
"version": "3.4.5",
|
||||
"version": "3.4.3",
|
||||
"description": "Astro and Tailwindcss boilerplate",
|
||||
"author": "zeon.studio",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<p align=center> If you find this project useful, please give it a ⭐ to show your support. </p>
|
||||
|
||||
<h2 align="center"> <a target="_blank" href="https://zeon.studio/preview?project=astroplate" rel="nofollow">👀 Demo</a> | <a target="_blank" href="https://pagespeed.web.dev/analysis/https-astroplate-netlify-app/yzx3foum3w?form_factor=desktop">Page Speed (100%)🚀</a>
|
||||
<h2 align="center"> <a target="_blank" href="https://astroplate.netlify.app/" rel="nofollow">👀 Demo</a> | <a target="_blank" href="https://pagespeed.web.dev/analysis/https-astroplate-netlify-app/yzx3foum3w?form_factor=desktop">Page Speed (100%)🚀</a>
|
||||
</h2>
|
||||
|
||||
<p align=center>
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
"logo_text": "Astroplate"
|
||||
},
|
||||
|
||||
"language": {
|
||||
"defaultLang": "en",
|
||||
"supported": ["", "en", "fr", "ar"]
|
||||
},
|
||||
|
||||
"settings": {
|
||||
"search": true,
|
||||
"sticky_header": true,
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"main": [
|
||||
{ "name": "الرئيسية", "url": "/" },
|
||||
{ "name": "نبذة عنا", "url": "/about" },
|
||||
{ "name": "العناصر", "url": "/elements" },
|
||||
{
|
||||
"name": "Pages",
|
||||
"url": "",
|
||||
"hasChildren": true,
|
||||
"children": [
|
||||
{ "name": "اتصل بنا", "url": "/contact" },
|
||||
{ "name": "المدونة", "url": "/blog" },
|
||||
{ "name": "المؤلفون", "url": "/authors" },
|
||||
{ "name": "التصنيفات", "url": "/categories" },
|
||||
{ "name": "العلامات", "url": "/tags" },
|
||||
{ "name": "صفحة 404", "url": "/404" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"footer": [
|
||||
{ "name": "العناصر", "url": "/elements" },
|
||||
{ "name": "سياسة الخصوصية", "url": "/privacy-policy" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"main": [
|
||||
{ "name": "Home", "url": "/" },
|
||||
{ "name": "About", "url": "/about" },
|
||||
{ "name": "Elements", "url": "/elements" },
|
||||
{
|
||||
"name": "Pages",
|
||||
"url": "",
|
||||
"hasChildren": true,
|
||||
"children": [
|
||||
{ "name": "Contact", "url": "/contact" },
|
||||
{ "name": "Blog", "url": "/blog" },
|
||||
{ "name": "Authors", "url": "/authors" },
|
||||
{ "name": "Categories", "url": "/categories" },
|
||||
{ "name": "Tags", "url": "/tags" },
|
||||
{ "name": "404 Page", "url": "/404" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"footer": [
|
||||
{ "name": "Elements", "url": "/elements" },
|
||||
{ "name": "Privacy Policy", "url": "/privacy-policy" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"main": [
|
||||
{ "name": "Accueil", "url": "/" },
|
||||
{ "name": "À propos", "url": "/about" },
|
||||
{ "name": "Éléments", "url": "/elements" },
|
||||
{
|
||||
"name": "Pages",
|
||||
"url": "",
|
||||
"hasChildren": true,
|
||||
"children": [
|
||||
{ "name": "Contact", "url": "/contact" },
|
||||
{ "name": "Blog", "url": "/blog" },
|
||||
{ "name": "Auteurs", "url": "/authors" },
|
||||
{ "name": "Catégories", "url": "/categories" },
|
||||
{ "name": "Étiquettes", "url": "/tags" },
|
||||
{ "name": "Page 404", "url": "/404" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"footer": [
|
||||
{ "name": "Éléments", "url": "/elements" },
|
||||
{ "name": "Politique de confidentialité", "url": "/privacy-policy" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: "مهلا، أنا جون دو!"
|
||||
meta_title: "About"
|
||||
description: "this is meta description"
|
||||
image: "/images/avatar.png"
|
||||
draft: false
|
||||
---
|
||||
|
||||
الشركة نفسها هي شركة ناجحة جدا. إنهم لا يعرفون فوائد الجسد، أو إلا أنهم سيحصلون عليه في أوقات أخرى، كلها، أوقات العمل، فهو يكره من هذا الوقت ولكن. يهرب من الملذات المحسوسة ليفترض أنها لا شيء، كل شيء أو، والألم هو الخيار الأكبر، فإنه أيسر عليه، وما يتبعه يقدمون الألم ونحوه! لأن وسيلة الحقيقة المذكورة تطرد اللذة وتمنع الألم، فهي تقدم كما لو
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: "المؤلفون"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
---
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: فلان الفلاني
|
||||
email: johndoe@email.com
|
||||
image: "/images/avatar.png"
|
||||
description: this is meta description
|
||||
social:
|
||||
- name: github
|
||||
icon: FaGithub
|
||||
link: https://github.com
|
||||
|
||||
- name: twitter
|
||||
icon: FaTwitter
|
||||
link: https://twitter.com
|
||||
|
||||
- name: linkedin
|
||||
icon: FaLinkedin
|
||||
link: https://linkedin.com
|
||||
---
|
||||
|
||||
lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostr navigation et dolore magna aliqua.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: سام ويلسون
|
||||
email: samwilson@email.com
|
||||
image: "/images/avatar.png"
|
||||
description: this is meta description
|
||||
social:
|
||||
- name: github
|
||||
icon: FaGithub
|
||||
link: https://github.com
|
||||
|
||||
- name: twitter
|
||||
icon: FaTwitter
|
||||
link: https://twitter.com
|
||||
|
||||
- name: linkedin
|
||||
icon: FaLinkedin
|
||||
link: https://linkedin.com
|
||||
---
|
||||
|
||||
lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostr navigation et dolore magna aliqua.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: وليام جاكوب
|
||||
email: williamjacob@email.com
|
||||
image: "/images/avatar.png"
|
||||
description: this is meta description
|
||||
social:
|
||||
- name: github
|
||||
icon: FaGithub
|
||||
link: https://github.com
|
||||
|
||||
- name: twitter
|
||||
icon: FaTwitter
|
||||
link: https://twitter.com
|
||||
|
||||
- name: linkedin
|
||||
icon: FaLinkedin
|
||||
link: https://linkedin.com
|
||||
---
|
||||
|
||||
lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostr navigation et dolore magna aliqua.
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: "منشورات المدونة"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
---
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "كيفية بناء تطبيق بالتكنولوجيا الحديثة"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
date: 2022-04-04T05:00:00Z
|
||||
image: "/images/image-placeholder.png"
|
||||
categories: ["Application", "Data", "Arabic"]
|
||||
author: "John Doe"
|
||||
tags: ["nextjs", "tailwind"]
|
||||
draft: false
|
||||
---
|
||||
|
||||
لا داعي للقلق بشأن إنشاء rutrum على سبيل المثال، venenatis sollicitudin urna. Aliquam عصر فولوتبات. عدد صحيح الاتحاد الأوروبي ipsum sem. Ut bibendum lacus الدهليزي مكسيموس سوسكيبيت. السيرة الذاتية الرائعة nibh iaculis neque blandit euismod.
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. لا حاجة إلى إنشاء aperiam. Itaque eligendi natus aperiam؟ استثناءات طاردة للسلبية خيار التعجيل السريع هو أديبيسسي دولوريم أوت إيوس!
|
||||
|
||||
## التصميم الإبداعي
|
||||
|
||||
Nam ut rutrum ex, venenatis sollicitudin urna. Aliquam عصر فولوتبات. عدد صحيح الاتحاد الأوروبي ipsum sem. Ut bibendum lacus الدهليزي مكسيموس suscipit. السيرة الذاتية الرائعة nibh iaculis neque blandit euismod.
|
||||
|
||||
> لوريم إيبسوم دولور الجلوس أميت كونسيكتور أديبيسينج إيليت. لا حاجة إلى إنشاء aperiam. Itaque eligendi natus aperiam؟ استثناءات طاردة للسلبية خيار التعجيل السريع هو أديبيسسي دولوريم أوت إيوس!
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. لا حاجة إلى إنشاء aperiam. Itaque eligendi natus aperiam؟ استثناءات طاردة للسلبية خيار التعجيل السريع هو أديبيسسي دولوريم أوت إيوس!
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
---
|
||||
# Banner
|
||||
banner:
|
||||
title: "القالب المبدئي المثالي الذي تحتاجه لبدء مشروعك الفلكي"
|
||||
content: "Astroplate هو قالب بداية مجاني مصمم باستخدام Astro وTailwindCSS، وهو يوفر كل ما تحتاجه لبدء مشروع Astro الخاص بك وتوفير الوقت الثمين."
|
||||
image: "/images/banner.png"
|
||||
button:
|
||||
enable: true
|
||||
label: "Get Started For Free"
|
||||
link: "https://github.com/zeon-studio/astroplate"
|
||||
|
||||
# Features
|
||||
features:
|
||||
- title: "What's Included in Astroplate"
|
||||
image: "/images/service-1.png"
|
||||
content: "Astroplate is a comprehensive starter template that includes everything you need to get started with your Astro project. What's Included in Astroplate"
|
||||
bulletpoints:
|
||||
- "10+ Pre-build pages"
|
||||
- "95+ Google Pagespeed Score"
|
||||
- "Build with Astro and TailwindCSS for easy and customizable styling"
|
||||
- "Fully responsive on all devices"
|
||||
- "SEO-optimized for better search engine rankings"
|
||||
- "**Open-source and free** for personal and commercial use"
|
||||
button:
|
||||
enable: false
|
||||
label: "Get Started Now"
|
||||
link: "#"
|
||||
|
||||
- title: "Discover the Key Features Of Astro"
|
||||
image: "/images/service-2.png"
|
||||
content: "Astro is an all-in-one web framework for building fast, content-focused websites. It offers a range of exciting features for developers and website creators. Some of the key features are:"
|
||||
bulletpoints:
|
||||
- "Zero JS, by default: No JavaScript runtime overhead to slow you down."
|
||||
- "Customizable: Tailwind, MDX, and 100+ other integrations to choose from."
|
||||
- "UI-agnostic: Supports React, Preact, Svelte, Vue, Solid, Lit and more."
|
||||
button:
|
||||
enable: true
|
||||
label: "Get Started Now"
|
||||
link: "https://github.com/zeon-studio/astroplate"
|
||||
|
||||
- title: "The Top Reasons to Choose Astro for Your Next Project"
|
||||
image: "/images/service-3.png"
|
||||
content: "With Astro, you can build modern and content-focused websites without sacrificing performance or ease of use."
|
||||
bulletpoints:
|
||||
- "Instantly load static sites for better user experience and SEO."
|
||||
- "Intuitive syntax and support for popular frameworks make learning and using Astro a breeze."
|
||||
- "Use any front-end library or framework, or build custom components, for any project size."
|
||||
- "Built on cutting-edge technology to keep your projects up-to-date with the latest web standards."
|
||||
button:
|
||||
enable: false
|
||||
label: ""
|
||||
link: ""
|
||||
---
|
||||
Executable
+255
@@ -0,0 +1,255 @@
|
||||
---
|
||||
title: "عناصر"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
draft: false
|
||||
---
|
||||
|
||||
# عنوان 1
|
||||
|
||||
## العنوان 2
|
||||
|
||||
### العنوان 3
|
||||
|
||||
#### العنوان 4
|
||||
|
||||
##### العنوان 5
|
||||
|
||||
###### العنوان 6
|
||||
|
||||
---
|
||||
|
||||
### فقرة
|
||||
|
||||
هل أتيت إلى هنا من أجل شيء محدد أم مجرد تقريع للرايكر بشكل عام؟ وبالانطلاق إلى أقصى سرعة ممكنة، ظهرت للحظة وكأنك في مكانين في الوقت نفسه. لدينا مخرب على متن الطائرة. نحن نعلم أنك تتعامل بالخام المسروق. لكني أريد أن أتحدث عن محاولة اغتيال الملازم وورف. هل يمكن لأي شخص البقاء على قيد الحياة داخل منطقة النقل العازلة لمدة 75 عامًا؟ قدر. إنه يحمي الحمقى والأطفال الصغار والسفن.
|
||||
|
||||
هل أتيت إلى هنا من أجل شيء محدد أم مجرد تقريع عام للرايكر؟ وبالانطلاق إلى أقصى سرعة ممكنة، ظهرت للحظة وكأنك في مكانين في الوقت نفسه. لدينا مخرب على متن الطائرة. نحن نعلم أنك تتعامل بالخام المسروق. لكني أريد أن أتحدث عن محاولة اغتيال الملازم وورف. هل يمكن لأي شخص البقاء على قيد الحياة داخل منطقة النقل العازلة لمدة 75 عامًا؟ قدر. إنه يحمي الحمقى والأطفال الصغار والسفن.
|
||||
|
||||
---
|
||||
|
||||
### توكيد
|
||||
|
||||
1. هل أتيت إلى هنا من أجل شيء **خاص** أم مجرد عام
|
||||
|
||||
2. هل أتيت إلى هنا من أجل شيء ما <ins>على وجه الخصوص</ins>
|
||||
|
||||
3. _هل أتيت إلى هنا_
|
||||
|
||||
4. هل أتيت إلى هنا من أجل ** شيء ما ** على وجه الخصوص
|
||||
|
||||
5. هل أتيت إلى هنا من أجل شيء محدد؟
|
||||
|
||||
6. هل أتيت إلى هنا من أجل شيء محدد؟
|
||||
|
||||
7. سيتم تحويل عناوين URL وعناوين URL الموجودة بين قوسين إلى روابط تلقائيًا. [http://www.example.com](http://www.example.com) أو
|
||||
|
||||
8. [http://www.example.com](http://www.example.com) وأحيانًا example.com (ولكن ليس على Github، على سبيل المثال).
|
||||
|
||||
---
|
||||
|
||||
### وصلة
|
||||
|
||||
[أنا رابط ذو نمط مضمّن](https://www.google.com)
|
||||
|
||||
[أنا رابط على شكل سطري يحمل عنوانًا](https://www.google.com "صفحة Google الرئيسية")
|
||||
|
||||
[أنا رابط ذو نمط مرجعي] [نص مرجعي عشوائي غير حساس لحالة الأحرف]
|
||||
|
||||
[أنا مرجع نسبي لملف مستودع](../blob/master/LICENSE)
|
||||
|
||||
[يمكنك استخدام الأرقام لتعريفات الارتباط ذات النمط المرجعي] [1]
|
||||
|
||||
أو اتركه فارغًا واستخدم [رابط النص نفسه].
|
||||
|
||||
example.com (ولكن ليس على Github، على سبيل المثال).
|
||||
|
||||
بعض النص لإظهار أن الروابط المرجعية يمكن أن تتبع لاحقًا.
|
||||
|
||||
[نص مرجعي عشوائي غير حساس لحالة الأحرف]: https://www.themefisher.com
|
||||
[1]: https://gethugothemes.com
|
||||
[رابط النص نفسه]: https://www.getjekyllthemes.com
|
||||
|
||||
---
|
||||
|
||||
### Ordered List
|
||||
|
||||
1. List item
|
||||
2. List item
|
||||
3. List item
|
||||
4. List item
|
||||
5. List item
|
||||
|
||||
---
|
||||
|
||||
### Unordered List
|
||||
|
||||
- List item
|
||||
- List item
|
||||
- List item
|
||||
- List item
|
||||
- List item
|
||||
|
||||
---
|
||||
|
||||
### Code and Syntax Highlighting
|
||||
|
||||
#### HTML
|
||||
|
||||
```html
|
||||
<ul>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="about/">About</a>
|
||||
</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### CSS
|
||||
|
||||
```css
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border: 0;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### JavaScript
|
||||
|
||||
```javascript
|
||||
window.addEventListener("load", (e) => {
|
||||
document.querySelector(".preloader").style.display = "none";
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Button
|
||||
|
||||
<Button label="Button" link="#" style="solid" />
|
||||
|
||||
---
|
||||
|
||||
### Quote
|
||||
|
||||
> Did you come here for something in particular or just general Riker-bashing? And blowing into maximum warp speed, you appeared for an instant to be in two places at once.
|
||||
|
||||
---
|
||||
|
||||
### Notice
|
||||
|
||||
<Notice type="note">This is a simple note.</Notice>
|
||||
|
||||
<Notice type="tip">This is a simple note.</Notice>
|
||||
|
||||
<Notice type="info">This is a simple note.</Notice>
|
||||
|
||||
<Notice type="warning">This is a simple note.</Notice>
|
||||
|
||||
---
|
||||
|
||||
### Tab
|
||||
|
||||
<Tabs client:load>
|
||||
|
||||
<Tab name="Tab 1">
|
||||
|
||||
#### Did you come here for something in particular?
|
||||
|
||||
Did you come here for something in particular or just general Riker-bashing? And blowing into maximum warp speed, you appeared for an instant to be in two places at once. We have a saboteur aboard. We know you’re dealing in stolen ore. But I wanna talk about the assassination attempt on Lieutenant Worf.
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab name="Tab 2">
|
||||
|
||||
#### I wanna talk about the assassination attempt
|
||||
|
||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||
|
||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab name="Tab 3">
|
||||
|
||||
#### We know you’re dealing in stolen ore
|
||||
|
||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||
|
||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo
|
||||
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
### Table
|
||||
|
||||
| # | First | Last | Handle |
|
||||
| :-- | :----------: | :----------: | -----------: |
|
||||
| 1 | Row:1 Cell:1 | Row:1 Cell:2 | Row:1 Cell:3 |
|
||||
| 2 | Row:2 Cell:1 | Row:2 Cell:2 | Row:2 Cell:3 |
|
||||
| 3 | Row:3 Cell:1 | Row:3 Cell:2 | Row:3 Cell:3 |
|
||||
|
||||
---
|
||||
|
||||
### Accordion
|
||||
|
||||
<Accordion client:load title="Why should you need to do this?">
|
||||
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion client:load title="How can I adjust Horizontal centering">
|
||||
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion client:load title="Should you use Negative margin?">
|
||||
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
|
||||
</Accordion>
|
||||
|
||||
---
|
||||
|
||||
### Image
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
### Youtube video
|
||||
|
||||
<Youtube client:load id="ZEe-IFezQok" title="Youtube Video Test Title" />
|
||||
|
||||
---
|
||||
|
||||
### Custom video
|
||||
|
||||
<Video
|
||||
width="100%"
|
||||
src="https://joy1.videvo.net/videvo_files/video/free/video0467/large_watermarked/_import_61516692993d77.04238324_preview.mp4"
|
||||
/>
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: "خصوصية"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
draft: false
|
||||
---
|
||||
|
||||
#### مسؤولية المساهمين
|
||||
|
||||
العميل مهم جدًا، العميل سيتبعه العميل. بوروس، حتى الآن أنت إيروس، ullamcorper id feugiat كل شخص ببعض السهام. كنت قبيحًا، لكن كتلة الرسوم الكاريكاتورية كانت حبلى بالجعبة. لا أريد ألم لاعب كرة قدم قوي. سيتم علاج Ultrices بالقوس من فراش المرض. تم إطلاق النار عليه بالسهام في المسار الكلي. كانت مشكلة القدر الساخن هي أنه يحتاج إلى الشوكولاتة. الآن المكتب ولكن في بعض الأحيان البحيرة. لكن من يهتم بالرسوم المتحركة
|
||||
|
||||
السعر بعض. إنه عنصر مهم للغاية، إيروس تينسيدونت، نيبه في الأسد. Malesuada نقية، بحيرة، ولكن لبعض الوقت معلقة. من يهتم بالوقت يريد أن يولد من القلق. ولكن يجب الاهتمام بها. يريد الاتحاد الأوروبي أن يولد من القلق، ويحتاج erhdfvssfvrgss إلى الرسوم الكاريكاتورية والعناصر. بحيرة يسهل السباحة فيها.
|
||||
|
||||
#### جمع المعلومات الشخصية
|
||||
|
||||
العميل مهم جدًا، العميل سيتبعه العميل. بوروس، حتى الآن أنت إيروس، ullamcorper id feugiat كل شخص ببعض السهام. كنت قبيحًا، لكن كتلة الرسوم الكاريكاتورية كانت حبلى بالجعبة. لا أريد ألم لاعب كرة قدم قوي. سيتم علاج Ultrices بالقوس من فراش المرض. تم إطلاق النار عليه بالسهام في دورة التعذيب. كانت مشكلة القدر الساخن هي أنه يحتاج إلى الشوكولاتة. الآن المكتب ولكن في بعض الأحيان البحيرة. لكن من يهتم بالرسوم المتحركة
|
||||
|
||||
#### حماية المعلومات الشخصية
|
||||
|
||||
العميل مهم جدًا، العميل سيتبعه العميل. بوروس، حتى الآن أنت إيروس، ullamcorper id feugiat كل شخص ببعض السهام. كنت قبيحًا، لكن كتلة الرسوم الكاريكاتورية كانت حبلى بالجعبة. لا أريد ألم لاعب كرة قدم قوي. سيتم علاج Ultrices بالقوس من فراش المرض. تم إطلاق النار عليه بالسهام في المسار الكلي.
|
||||
|
||||
كانت المشكلة أنه كان بحاجة إلى الشوكولاتة. الآن المكتب ولكن في بعض الأحيان البحيرة. لكن من يهتم بالرسوم المتحركة
|
||||
العميل مهم جدًا، العميل سيتبعه العميل. بوروس، حتى الآن أنت إيروس، ullamcorper id feugiat
|
||||
|
||||
#### تغييرات سياسة الخصوصية
|
||||
|
||||
1. تم تصميم جميع عناصر Themefisher لتتوافق مع الأحدث، ونحن نتحقق من كل شيء
|
||||
2. التعليقات التي تهدد أو تضر بسمعة أي شخص أو منظمة
|
||||
3. المعلومات الشخصية بما في ذلك، على سبيل المثال لا الحصر، عناوين البريد الإلكتروني وأرقام الهواتف
|
||||
4. أي تحديث يأتي في التكنولوجيا سوف يحصل العميل على إشعار تلقائي.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
enable: true
|
||||
title: "هل أنت مستعد لبناء مشروعك القادم مع Astro؟"
|
||||
image: "/images/call-to-action.png"
|
||||
description: "اكتشف مستقبل تطوير الويب مع Astroplate وAstro. قم ببناء مواقع ثابتة بسرعة البرق بكل سهولة ومرونة."
|
||||
button:
|
||||
enable: true
|
||||
label: "نبدأ الآن"
|
||||
link: "https://github.com/zeon-studio/astroplate"
|
||||
---
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
enable: true
|
||||
title: "ما يقوله المستخدمون عن Astroplate"
|
||||
description: "لا تأخذ كلمتنا على محمل الجد - استمع إلى بعض مستخدمينا الراضين! تحقق من بعض شهاداتنا أدناه لترى ما يقوله الآخرون عن Astroplate."
|
||||
|
||||
# Testimonials
|
||||
testimonials:
|
||||
- name: "Marvin McKinney"
|
||||
designation: "Web Designer"
|
||||
avatar: "/images/avatar-sm.png"
|
||||
content: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui iusto illo molestias, assumenda expedita commodi inventore non itaque molestiae voluptatum dolore, facilis sapiente, repellat veniam."
|
||||
|
||||
- name: "Marvin McKinney"
|
||||
designation: "Web Designer"
|
||||
avatar: "/images/avatar-sm.png"
|
||||
content: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui iusto illo molestias, assumenda expedita commodi inventore non itaque molestiae voluptatum dolore, facilis sapiente, repellat veniam."
|
||||
|
||||
- name: "Marvin McKinney"
|
||||
designation: "Web Designer"
|
||||
avatar: "/images/avatar-sm.png"
|
||||
content: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui iusto illo molestias, assumenda expedita commodi inventore non itaque molestiae voluptatum dolore, facilis sapiente, repellat veniam."
|
||||
|
||||
- name: "Marvin McKinney"
|
||||
designation: "Web Designer"
|
||||
avatar: "/images/avatar-sm.png"
|
||||
content: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui iusto illo molestias, assumenda expedita commodi inventore non itaque molestiae voluptatum dolore, facilis sapiente, repellat veniam."
|
||||
---
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "How to build an Application with modern Technology"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
date: 2022-04-04T05:00:00Z
|
||||
image: "/images/image-placeholder.png"
|
||||
categories: ["Technology", "Data"]
|
||||
author: "Sam Wilson"
|
||||
tags: ["technology", "tailwind"]
|
||||
draft: false
|
||||
---
|
||||
|
||||
Nemo vel ad consectetur namut rutrum ex, venenatis sollicitudin urna. Aliquam erat volutpat. Integer eu ipsum sem. Ut bibendum lacus vestibulum maximus suscipit. Quisque vitae nibh iaculis neque blandit euismod.
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
|
||||
## Creative Design
|
||||
|
||||
Nam ut rutrum ex, venenatis sollicitudin urna. Aliquam erat volutpat. Integer eu ipsum sem. Ut bibendum lacus vestibulum maximus suscipit. Quisque vitae nibh iaculis neque blandit euismod.
|
||||
|
||||
> Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "How to build an Application with modern Technology"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
date: 2022-04-04T05:00:00Z
|
||||
image: "/images/image-placeholder.png"
|
||||
categories: ["Software"]
|
||||
author: "John Doe"
|
||||
tags: ["software", "tailwind"]
|
||||
draft: false
|
||||
---
|
||||
|
||||
Nemo vel ad consectetur namut rutrum ex, venenatis sollicitudin urna. Aliquam erat volutpat. Integer eu ipsum sem. Ut bibendum lacus vestibulum maximus suscipit. Quisque vitae nibh iaculis neque blandit euismod.
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
|
||||
## Creative Design
|
||||
|
||||
Nam ut rutrum ex, venenatis sollicitudin urna. Aliquam erat volutpat. Integer eu ipsum sem. Ut bibendum lacus vestibulum maximus suscipit. Quisque vitae nibh iaculis neque blandit euismod.
|
||||
|
||||
> Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "How to build an Application with modern Technology"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
date: 2022-04-04T05:00:00Z
|
||||
image: "/images/image-placeholder.png"
|
||||
categories: ["Architecture"]
|
||||
author: "John Doe"
|
||||
tags: ["silicon", "technology"]
|
||||
draft: false
|
||||
---
|
||||
|
||||
Nemo vel ad consectetur namut rutrum ex, venenatis sollicitudin urna. Aliquam erat volutpat. Integer eu ipsum sem. Ut bibendum lacus vestibulum maximus suscipit. Quisque vitae nibh iaculis neque blandit euismod.
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
|
||||
## Creative Design
|
||||
|
||||
Nam ut rutrum ex, venenatis sollicitudin urna. Aliquam erat volutpat. Integer eu ipsum sem. Ut bibendum lacus vestibulum maximus suscipit. Quisque vitae nibh iaculis neque blandit euismod.
|
||||
|
||||
> Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: "Contact"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
draft: false
|
||||
---
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: "Hé, je suis John Doe !"
|
||||
meta_title: "About"
|
||||
description: "this is meta description"
|
||||
image: "/images/avatar.png"
|
||||
draft: false
|
||||
---
|
||||
|
||||
L'entreprise elle-même est une entreprise très prospère. Ils ne connaissent pas les bienfaits du corps, ou sauf qu'ils le recevront à d'autres moments, le tout, les temps de travail, qu'il déteste à partir de ce moment mais. Il fuit les plaisirs perçus pour être supposés n'être rien, tout ou, et la douleur est ce qui est la plus grande option, car cela lui est facile, et avec ce que cela s'ensuit, ils lui procurent de la douleur et ainsi de suite ! Car ledit expédient de la vérité repousse le plaisir et empêche la douleur, ils fournissent comme si
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: "Auteurs"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
---
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: John Doe
|
||||
email: johndoe@email.com
|
||||
image: "/images/avatar.png"
|
||||
description: this is meta description
|
||||
social:
|
||||
- name: github
|
||||
icon: FaGithub
|
||||
link: https://github.com
|
||||
|
||||
- name: twitter
|
||||
icon: FaTwitter
|
||||
link: https://twitter.com
|
||||
|
||||
- name: linkedin
|
||||
icon: FaLinkedin
|
||||
link: https://linkedin.com
|
||||
---
|
||||
|
||||
lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostr navigation et dolore magna aliqua.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: Sam Wilson
|
||||
email: samwilson@email.com
|
||||
image: "/images/avatar.png"
|
||||
description: this is meta description
|
||||
social:
|
||||
- name: github
|
||||
icon: FaGithub
|
||||
link: https://github.com
|
||||
|
||||
- name: twitter
|
||||
icon: FaTwitter
|
||||
link: https://twitter.com
|
||||
|
||||
- name: linkedin
|
||||
icon: FaLinkedin
|
||||
link: https://linkedin.com
|
||||
---
|
||||
|
||||
lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostr navigation et dolore magna aliqua.
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: Guillaume Jacob
|
||||
email: williamjacob@email.com
|
||||
image: "/images/avatar.png"
|
||||
description: this is meta description
|
||||
social:
|
||||
- name: github
|
||||
icon: FaGithub
|
||||
link: https://github.com
|
||||
|
||||
- name: twitter
|
||||
icon: FaTwitter
|
||||
link: https://twitter.com
|
||||
|
||||
- name: linkedin
|
||||
icon: FaLinkedin
|
||||
link: https://linkedin.com
|
||||
---
|
||||
|
||||
lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostr navigation et dolore magna aliqua.
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: "Articles de blog"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
---
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "Comment créer une application avec la technologie moderne"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
date: 2022-04-04T05:00:00Z
|
||||
image: "/images/image-placeholder.png"
|
||||
categories: ["Application", "Data"]
|
||||
author: "John Doe"
|
||||
tags: ["nextjs", "tailwind"]
|
||||
draft: false
|
||||
---
|
||||
|
||||
Personne ne veut même sortir un maquillage de l'urne des soins empoisonnés. C'était un week-end. Je suis un footballeur complet. Pour s'abreuver, le lac emprunte le plus grand portique. Chacune des cibles de la vie ne flatte pas Euismod.
|
||||
|
||||
L'entreprise elle-même est une entreprise très prospère. Personne ne prend même la peine de l'ouvrir. Alors je vais ouvrir la naissance pour choisir ? Être rejeté par certaines personnes est une option pratique pour le présent pour avoir une douleur comme la sienne !
|
||||
|
||||
## Design créatif
|
||||
|
||||
Pour se maquiller, l'urne du solludicinum empoisonné. C'était un week-end. Je suis un footballeur complet. Pour s'abreuver, le lac emprunte le plus grand portique. Chacune des cibles de la vie ne flatte pas Euismod.
|
||||
|
||||
> Le client lui-même doit être en mesure de poursuivre une élite adipisicing. Personne ne prend même la peine de l'ouvrir. Alors je vais ouvrir la naissance pour choisir ? Être rejeté par certaines personnes est une option pratique pour le présent pour avoir une douleur comme la sienne !
|
||||
|
||||
L'entreprise elle-même est une entreprise très prospère. Personne ne prend même la peine de l'ouvrir. Alors je vais ouvrir la naissance pour choisir ? Être rejeté par certaines personnes est une option pratique pour le présent pour avoir une douleur comme la sienne !
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "How to build an Application with modern Technology"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
date: 2022-04-04T05:00:00Z
|
||||
image: "/images/image-placeholder.png"
|
||||
categories: ["Technology", "Data"]
|
||||
author: "Sam Wilson"
|
||||
tags: ["technology", "tailwind"]
|
||||
draft: false
|
||||
---
|
||||
|
||||
Nemo vel ad consectetur namut rutrum ex, venenatis sollicitudin urna. Aliquam erat volutpat. Integer eu ipsum sem. Ut bibendum lacus vestibulum maximus suscipit. Quisque vitae nibh iaculis neque blandit euismod.
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
|
||||
## Creative Design
|
||||
|
||||
Nam ut rutrum ex, venenatis sollicitudin urna. Aliquam erat volutpat. Integer eu ipsum sem. Ut bibendum lacus vestibulum maximus suscipit. Quisque vitae nibh iaculis neque blandit euismod.
|
||||
|
||||
> Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "How to build an Application with modern Technology"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
date: 2022-04-04T05:00:00Z
|
||||
image: "/images/image-placeholder.png"
|
||||
categories: ["Software"]
|
||||
author: "John Doe"
|
||||
tags: ["software", "tailwind"]
|
||||
draft: false
|
||||
---
|
||||
|
||||
Nemo vel ad consectetur namut rutrum ex, venenatis sollicitudin urna. Aliquam erat volutpat. Integer eu ipsum sem. Ut bibendum lacus vestibulum maximus suscipit. Quisque vitae nibh iaculis neque blandit euismod.
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
|
||||
## Creative Design
|
||||
|
||||
Nam ut rutrum ex, venenatis sollicitudin urna. Aliquam erat volutpat. Integer eu ipsum sem. Ut bibendum lacus vestibulum maximus suscipit. Quisque vitae nibh iaculis neque blandit euismod.
|
||||
|
||||
> Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: "How to build an Application with modern Technology"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
date: 2022-04-04T05:00:00Z
|
||||
image: "/images/image-placeholder.png"
|
||||
categories: ["Architecture"]
|
||||
author: "John Doe"
|
||||
tags: ["silicon", "technology"]
|
||||
draft: false
|
||||
---
|
||||
|
||||
Nemo vel ad consectetur namut rutrum ex, venenatis sollicitudin urna. Aliquam erat volutpat. Integer eu ipsum sem. Ut bibendum lacus vestibulum maximus suscipit. Quisque vitae nibh iaculis neque blandit euismod.
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
|
||||
## Creative Design
|
||||
|
||||
Nam ut rutrum ex, venenatis sollicitudin urna. Aliquam erat volutpat. Integer eu ipsum sem. Ut bibendum lacus vestibulum maximus suscipit. Quisque vitae nibh iaculis neque blandit euismod.
|
||||
|
||||
> Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nemo vel ad consectetur ut aperiam. Itaque eligendi natus aperiam? Excepturi repellendus consequatur quibusdam optio expedita praesentium est adipisci dolorem ut eius!
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: "Contact"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
draft: false
|
||||
---
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
---
|
||||
# Banner
|
||||
banner:
|
||||
title: "Le modèle de démarrage ultime dont vous avez besoin pour démarrer votre projet Astro"
|
||||
content: "Astroplate est un modèle de démarrage gratuit construit avec Astro et TailwindCSS, fournissant tout ce dont vous avez besoin pour démarrer votre projet Astro et gagner un temps précieux."
|
||||
image: "/images/banner.png"
|
||||
button:
|
||||
enable: true
|
||||
label: "Get Started For Free"
|
||||
link: "https://github.com/zeon-studio/astroplate"
|
||||
|
||||
# Features
|
||||
features:
|
||||
- title: "What's Included in Astroplate"
|
||||
image: "/images/service-1.png"
|
||||
content: "Astroplate is a comprehensive starter template that includes everything you need to get started with your Astro project. What's Included in Astroplate"
|
||||
bulletpoints:
|
||||
- "10+ Pre-build pages"
|
||||
- "95+ Google Pagespeed Score"
|
||||
- "Build with Astro and TailwindCSS for easy and customizable styling"
|
||||
- "Fully responsive on all devices"
|
||||
- "SEO-optimized for better search engine rankings"
|
||||
- "**Open-source and free** for personal and commercial use"
|
||||
button:
|
||||
enable: false
|
||||
label: "Get Started Now"
|
||||
link: "#"
|
||||
|
||||
- title: "Discover the Key Features Of Astro"
|
||||
image: "/images/service-2.png"
|
||||
content: "Astro is an all-in-one web framework for building fast, content-focused websites. It offers a range of exciting features for developers and website creators. Some of the key features are:"
|
||||
bulletpoints:
|
||||
- "Zero JS, by default: No JavaScript runtime overhead to slow you down."
|
||||
- "Customizable: Tailwind, MDX, and 100+ other integrations to choose from."
|
||||
- "UI-agnostic: Supports React, Preact, Svelte, Vue, Solid, Lit and more."
|
||||
button:
|
||||
enable: true
|
||||
label: "Get Started Now"
|
||||
link: "https://github.com/zeon-studio/astroplate"
|
||||
|
||||
- title: "The Top Reasons to Choose Astro for Your Next Project"
|
||||
image: "/images/service-3.png"
|
||||
content: "With Astro, you can build modern and content-focused websites without sacrificing performance or ease of use."
|
||||
bulletpoints:
|
||||
- "Instantly load static sites for better user experience and SEO."
|
||||
- "Intuitive syntax and support for popular frameworks make learning and using Astro a breeze."
|
||||
- "Use any front-end library or framework, or build custom components, for any project size."
|
||||
- "Built on cutting-edge technology to keep your projects up-to-date with the latest web standards."
|
||||
button:
|
||||
enable: false
|
||||
label: ""
|
||||
link: ""
|
||||
---
|
||||
Executable
+255
@@ -0,0 +1,255 @@
|
||||
---
|
||||
title: "Éléments"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
draft: false
|
||||
---
|
||||
|
||||
# Rubrique 1
|
||||
|
||||
## Titre 2
|
||||
|
||||
### Titre 3
|
||||
|
||||
#### Rubrique 4
|
||||
|
||||
##### Rubrique 5
|
||||
|
||||
###### Rubrique 6
|
||||
|
||||
---
|
||||
|
||||
### Paragraphe
|
||||
|
||||
Êtes-vous venu ici pour quelque chose en particulier ou simplement pour dénigrer Riker en général ? Et en soufflant à la vitesse de distorsion maximale, vous avez semblé pendant un instant vous trouver à deux endroits à la fois. Nous avons un saboteur à bord. Nous savons que vous faites du trafic de minerai volé. Mais je veux parler de la tentative d'assassinat du lieutenant Worf. Quelqu’un pourrait-il survivre dans une zone tampon de transporteur pendant 75 ans ? Destin. Il protège les imbéciles, les petits enfants et les bateaux.
|
||||
|
||||
Êtes-vous venu ici pour quelque chose en particulier ou simplement pour dénigrer Riker en général ? Et en soufflant à la vitesse de distorsion maximale, vous avez semblé pendant un instant être à deux endroits à la fois. Nous avons un saboteur à bord. Nous savons que vous faites du trafic de minerai volé. Mais je veux parler de la tentative d'assassinat du lieutenant Worf. Quelqu’un pourrait-il survivre dans une zone tampon de transporteur pendant 75 ans ? Destin. Il protège les imbéciles, les petits enfants et les bateaux.
|
||||
|
||||
---
|
||||
|
||||
### Accent
|
||||
|
||||
1. Êtes-vous venu ici pour quelque chose en **particulier** ou simplement en général
|
||||
|
||||
2. Êtes-vous venu ici pour quelque chose en <ins>particulier</ins>
|
||||
|
||||
3. _Êtes-vous venu ici_
|
||||
|
||||
4. Êtes-vous venu ici pour **quelque chose** en particulier
|
||||
|
||||
5. Êtes-vous venu ici pour quelque chose en particulier
|
||||
|
||||
6. Êtes-vous venu ici pour quelque chose en particulier
|
||||
|
||||
7. Les URL et les URL entre crochets seront automatiquement transformées en liens. [http://www.example.com](http://www.example.com) ou
|
||||
|
||||
8. [http://www.example.com](http://www.example.com) et parfois example.com (mais pas sur Github, par exemple).
|
||||
|
||||
---
|
||||
|
||||
### Lien
|
||||
|
||||
[Je suis un lien de style en ligne](https://www.google.com)
|
||||
|
||||
[Je suis un lien de style en ligne avec un titre](https://www.google.com "Page d'accueil de Google")
|
||||
|
||||
[Je suis un lien de style référence][texte de référence arbitraire, insensible à la casse]
|
||||
|
||||
[Je suis une référence relative à un fichier de référentiel](../blob/master/LICENSE)
|
||||
|
||||
[Vous pouvez utiliser des nombres pour les définitions de liens de style référence][1]
|
||||
|
||||
Ou laissez-le vide et utilisez le [texte du lien lui-même].
|
||||
|
||||
example.com (mais pas sur Github, par exemple).
|
||||
|
||||
Un peu de texte pour montrer que les liens de référence peuvent suivre plus tard.
|
||||
|
||||
[texte de référence arbitraire, insensible à la casse] : https://www.themefisher.com
|
||||
[1] : https://gethugothemes.com
|
||||
[texte du lien lui-même] : https://www.getjekyllthemes.com
|
||||
|
||||
---
|
||||
|
||||
### Ordered List
|
||||
|
||||
1. List item
|
||||
2. List item
|
||||
3. List item
|
||||
4. List item
|
||||
5. List item
|
||||
|
||||
---
|
||||
|
||||
### Unordered List
|
||||
|
||||
- List item
|
||||
- List item
|
||||
- List item
|
||||
- List item
|
||||
- List item
|
||||
|
||||
---
|
||||
|
||||
### Code and Syntax Highlighting
|
||||
|
||||
#### HTML
|
||||
|
||||
```html
|
||||
<ul>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="about/">About</a>
|
||||
</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### CSS
|
||||
|
||||
```css
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border: 0;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### JavaScript
|
||||
|
||||
```javascript
|
||||
window.addEventListener("load", (e) => {
|
||||
document.querySelector(".preloader").style.display = "none";
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Button
|
||||
|
||||
<Button label="Button" link="#" style="solid" />
|
||||
|
||||
---
|
||||
|
||||
### Quote
|
||||
|
||||
> Did you come here for something in particular or just general Riker-bashing? And blowing into maximum warp speed, you appeared for an instant to be in two places at once.
|
||||
|
||||
---
|
||||
|
||||
### Notice
|
||||
|
||||
<Notice type="note">This is a simple note.</Notice>
|
||||
|
||||
<Notice type="tip">This is a simple note.</Notice>
|
||||
|
||||
<Notice type="info">This is a simple note.</Notice>
|
||||
|
||||
<Notice type="warning">This is a simple note.</Notice>
|
||||
|
||||
---
|
||||
|
||||
### Tab
|
||||
|
||||
<Tabs client:load>
|
||||
|
||||
<Tab name="Tab 1">
|
||||
|
||||
#### Did you come here for something in particular?
|
||||
|
||||
Did you come here for something in particular or just general Riker-bashing? And blowing into maximum warp speed, you appeared for an instant to be in two places at once. We have a saboteur aboard. We know you’re dealing in stolen ore. But I wanna talk about the assassination attempt on Lieutenant Worf.
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab name="Tab 2">
|
||||
|
||||
#### I wanna talk about the assassination attempt
|
||||
|
||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||
|
||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab name="Tab 3">
|
||||
|
||||
#### We know you’re dealing in stolen ore
|
||||
|
||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
|
||||
|
||||
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo
|
||||
|
||||
</Tab>
|
||||
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
### Table
|
||||
|
||||
| # | First | Last | Handle |
|
||||
| :-- | :----------: | :----------: | -----------: |
|
||||
| 1 | Row:1 Cell:1 | Row:1 Cell:2 | Row:1 Cell:3 |
|
||||
| 2 | Row:2 Cell:1 | Row:2 Cell:2 | Row:2 Cell:3 |
|
||||
| 3 | Row:3 Cell:1 | Row:3 Cell:2 | Row:3 Cell:3 |
|
||||
|
||||
---
|
||||
|
||||
### Accordion
|
||||
|
||||
<Accordion client:load title="Why should you need to do this?">
|
||||
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion client:load title="How can I adjust Horizontal centering">
|
||||
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion client:load title="Should you use Negative margin?">
|
||||
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
- This is a thing.
|
||||
|
||||
</Accordion>
|
||||
|
||||
---
|
||||
|
||||
### Image
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
### Youtube video
|
||||
|
||||
<Youtube client:load id="ZEe-IFezQok" title="Youtube Video Test Title" />
|
||||
|
||||
---
|
||||
|
||||
### Custom video
|
||||
|
||||
<Video
|
||||
width="100%"
|
||||
src="https://joy1.videvo.net/videvo_files/video/free/video0467/large_watermarked/_import_61516692993d77.04238324_preview.mp4"
|
||||
/>
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: "Confidentialité"
|
||||
meta_title: ""
|
||||
description: "this is meta description"
|
||||
draft: false
|
||||
---
|
||||
|
||||
#### Responsabilité des contributeurs
|
||||
|
||||
Le client est très important, le client sera suivi par le client. Purus, jusqu'à présent tu es eros, ullamcorper id feugiat chaque personne avec quelques flèches. J'étais laide, mais la masse des dessins animés était grosse d'un frémissement. Je ne veux pas de la douleur d’un footballeur puissant. Ultrices amoat, dans sera traité de l'arc du lit de la maladie. Il a été touché par des flèches lors d'un cours de torture. Le problème avec la fondue, c'est qu'il avait besoin de chocolat. Maintenant le bureau mais parfois le lac. Mais qui se soucie des dessins animés
|
||||
|
||||
le prix peut être certain. C'est un élément très important, tincidunt eros, nibh en lion. Malesuada est un lac pur, mais suspendu pendant un certain temps. Qui se soucie du temps, veut naître. Mais il faut en prendre soin. Eu veut naître du souci erhdfvssfvrgss a besoin de dessins animés et d'éléments. Un lac dans lequel il est facile de se baigner.
|
||||
|
||||
#### Collecte d'informations personnelles
|
||||
|
||||
Le client est très important, le client sera suivi par le client. Purus, jusqu'à présent tu es eros, ullamcorper id feugiat chaque personne avec quelques flèches. J'étais laide, mais la masse des dessins animés était grosse d'un frémissement. Ne me donne pas la douleur d'un joueur de football puissant. Les ultrices vont être guéries par l'arc du lit de la maladie. Il a été touché par des flèches lors d'un cours de torture. Le problème avec la fondue, c'est qu'il avait besoin de chocolat. Maintenant le bureau mais parfois le lac. Mais qui se soucie des dessins animés ?
|
||||
|
||||
#### Protection des informations personnelles
|
||||
|
||||
Le client est très important, le client sera suivi par le client. Purus, jusqu'à présent tu es eros, ullamcorper id feugiat chaque personne avec quelques flèches. J'étais laide, mais la masse des dessins animés était grosse d'un frémissement. Je ne veux pas de la douleur d’un footballeur puissant. Les ultrices vont être guéries par l'arc du lit de la maladie. Il a été touché par des flèches lors d'un cours de macro.
|
||||
|
||||
Le problème avec la marmite, c'était qu'il avait besoin de chocolat. Maintenant le bureau mais parfois le lac. Mais qui se soucie des dessins animés ?
|
||||
Le client est très important, le client sera suivi par le client. Purus, jusqu'à maintenant tu es eros, ullamcorper id feugiat
|
||||
|
||||
#### Modifications de la politique de confidentialité
|
||||
|
||||
1. Tous les articles Themefisher sont conçus pour être les plus récents, nous vérifions tous
|
||||
2. commentaires qui menacent ou nuisent à la réputation de toute personne ou organisation
|
||||
3. informations personnelles, y compris, sans toutefois s'y limiter, les adresses e-mail et les numéros de téléphone
|
||||
4. Toute mise à jour arrive. Le client technologique recevra une notification automatique.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
enable: true
|
||||
title: "Prêt à construire votre prochain projet avec Astro ?"
|
||||
image: "/images/call-to-action.png"
|
||||
description: "Expérimente le futur du développement web avec Astroplate et Astro. Créez des sites statiques à charge rapide et personnalisables en toute facilité."
|
||||
button:
|
||||
enable: true
|
||||
label: "Commencez maintenant"
|
||||
link: "https://github.com/zeon-studio/astroplate"
|
||||
---
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
enable: true
|
||||
title: "Ce que disent les utilisateurs à propos d'Astroplate"
|
||||
description: "Ne vous contentez pas de nous croire sur parole : écoutez certains de nos utilisateurs satisfaits ! Consultez certains de nos témoignages ci-dessous pour voir ce que d’autres disent à propos d’Astroplate."
|
||||
|
||||
# Testimonials
|
||||
testimonials:
|
||||
- name: "Marvin McKinney"
|
||||
designation: "Web Designer"
|
||||
avatar: "/images/avatar-sm.png"
|
||||
content: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui iusto illo molestias, assumenda expedita commodi inventore non itaque molestiae voluptatum dolore, facilis sapiente, repellat veniam."
|
||||
|
||||
- name: "Marvin McKinney"
|
||||
designation: "Web Designer"
|
||||
avatar: "/images/avatar-sm.png"
|
||||
content: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui iusto illo molestias, assumenda expedita commodi inventore non itaque molestiae voluptatum dolore, facilis sapiente, repellat veniam."
|
||||
|
||||
- name: "Marvin McKinney"
|
||||
designation: "Web Designer"
|
||||
avatar: "/images/avatar-sm.png"
|
||||
content: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui iusto illo molestias, assumenda expedita commodi inventore non itaque molestiae voluptatum dolore, facilis sapiente, repellat veniam."
|
||||
|
||||
- name: "Marvin McKinney"
|
||||
designation: "Web Designer"
|
||||
avatar: "/images/avatar-sm.png"
|
||||
content: "Lorem ipsum dolor sit amet consectetur adipisicing elit. Qui iusto illo molestias, assumenda expedita commodi inventore non itaque molestiae voluptatum dolore, facilis sapiente, repellat veniam."
|
||||
---
|
||||
@@ -0,0 +1,42 @@
|
||||
[
|
||||
{
|
||||
"id": "get_started",
|
||||
"translation": "البدء"
|
||||
},
|
||||
{
|
||||
"id": "read_more",
|
||||
"translation": "Read More"
|
||||
},
|
||||
{
|
||||
"id": "full_name",
|
||||
"translation": "الاسم الكامل"
|
||||
},
|
||||
{
|
||||
"id": "working_mail",
|
||||
"translation": "بريد العمل"
|
||||
},
|
||||
{
|
||||
"id": "anything_else",
|
||||
"translation": "أي شيء آخر؟"
|
||||
},
|
||||
{
|
||||
"id": "contact_message_placeholder",
|
||||
"translation": "الرسالة تذهب هنا..."
|
||||
},
|
||||
{
|
||||
"id": "submit",
|
||||
"translation": "يُقدِّم"
|
||||
},
|
||||
{
|
||||
"id": "page_not_found",
|
||||
"translation": "الصفحة غير موجودة"
|
||||
},
|
||||
{
|
||||
"id": "page_not_found_content",
|
||||
"translation": "ربما تمت إزالة الصفحة التي تبحث عنها، أو تم تغيير اسمها، أو أنها غير متاحة مؤقتًا."
|
||||
},
|
||||
{
|
||||
"id": "back_to_home",
|
||||
"translation": "العودة إلى المنزل"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,42 @@
|
||||
[
|
||||
{
|
||||
"id": "get_started",
|
||||
"translation": "Get Started"
|
||||
},
|
||||
{
|
||||
"id": "read_more",
|
||||
"translation": "Read More"
|
||||
},
|
||||
{
|
||||
"id": "full_name",
|
||||
"translation": "Full Name"
|
||||
},
|
||||
{
|
||||
"id": "working_mail",
|
||||
"translation": "Working Mail"
|
||||
},
|
||||
{
|
||||
"id": "anything_else",
|
||||
"translation": "Anything else?"
|
||||
},
|
||||
{
|
||||
"id": "contact_message_placeholder",
|
||||
"translation": "Message goes here..."
|
||||
},
|
||||
{
|
||||
"id": "submit",
|
||||
"translation": "Submit"
|
||||
},
|
||||
{
|
||||
"id": "page_not_found",
|
||||
"translation": "Page Not Found"
|
||||
},
|
||||
{
|
||||
"id": "page_not_found_content",
|
||||
"translation": "The page you are looking for might have been removed, had its name changed, or is temporarily unavailable."
|
||||
},
|
||||
{
|
||||
"id": "back_to_home",
|
||||
"translation": "Back to home"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,42 @@
|
||||
[
|
||||
{
|
||||
"id": "get_started",
|
||||
"translation": "Commencer"
|
||||
},
|
||||
{
|
||||
"id": "read_more",
|
||||
"translation": "Read More"
|
||||
},
|
||||
{
|
||||
"id": "full_name",
|
||||
"translation": "Nom et prénom"
|
||||
},
|
||||
{
|
||||
"id": "working_mail",
|
||||
"translation": "Courrier de travail"
|
||||
},
|
||||
{
|
||||
"id": "anything_else",
|
||||
"translation": "Rien d'autre?"
|
||||
},
|
||||
{
|
||||
"id": "contact_message_placeholder",
|
||||
"translation": "Le message va ici..."
|
||||
},
|
||||
{
|
||||
"id": "submit",
|
||||
"translation": "Soumettre"
|
||||
},
|
||||
{
|
||||
"id": "page_not_found",
|
||||
"translation": "Page non trouvée"
|
||||
},
|
||||
{
|
||||
"id": "page_not_found_content",
|
||||
"translation": "La page que vous recherchez a peut-être été supprimée, son nom a changé ou est temporairement indisponible."
|
||||
},
|
||||
{
|
||||
"id": "back_to_home",
|
||||
"translation": "De retour à la maison"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,63 @@
|
||||
import enDataJSON from './en.json';
|
||||
import frDataJSON from './fr.json';
|
||||
import arDataJSON from './ar.json';
|
||||
|
||||
|
||||
interface TranslationItem {
|
||||
id: string;
|
||||
translation: string;
|
||||
}
|
||||
|
||||
export function convertJsonToUiObject(jsonData: TranslationItem[], language: string): Record<string, Record<string, string>> {
|
||||
const ui: Record<string, Record<string, string>> = {};
|
||||
ui[language] = {};
|
||||
|
||||
for (const item of jsonData) {
|
||||
ui[language][item.id] = item.translation;
|
||||
}
|
||||
|
||||
return ui;
|
||||
}
|
||||
|
||||
|
||||
export const ui = {
|
||||
...convertJsonToUiObject(enDataJSON, 'en'),
|
||||
...convertJsonToUiObject(frDataJSON, 'fr'),
|
||||
...convertJsonToUiObject(arDataJSON, 'ar')
|
||||
} as const;
|
||||
|
||||
|
||||
// import { readdirSync } from 'fs';
|
||||
// import path from 'path';
|
||||
// import { fileURLToPath } from 'url';
|
||||
|
||||
// interface TranslationItem {
|
||||
// id: string;
|
||||
// translation: string;
|
||||
// }
|
||||
|
||||
// function convertJsonToUiObject(jsonData: TranslationItem[]): Record<string, string> {
|
||||
// const ui: Record<string, string> = {};
|
||||
|
||||
// for (const item of jsonData) {
|
||||
// ui[item.id] = item.translation;
|
||||
// }
|
||||
|
||||
// return ui;
|
||||
// }
|
||||
|
||||
// const __filename = fileURLToPath(import.meta.url);
|
||||
// const i18nFolderPath = path.join(path.dirname(__filename));
|
||||
// const ui: Record<string, Record<string, string>> = {};
|
||||
|
||||
// readdirSync(i18nFolderPath).forEach((file) => {
|
||||
// if (file.endsWith('.json')) {
|
||||
// const language = file.split('.')[0];
|
||||
// import(path.join(i18nFolderPath, file)).then((module) => {
|
||||
// const jsonData: TranslationItem[] = module.default;
|
||||
// ui[language] = convertJsonToUiObject(jsonData);
|
||||
// });
|
||||
// }
|
||||
// });
|
||||
|
||||
// export { ui };
|
||||
+11
-10
@@ -18,12 +18,12 @@ let fontPrimary, fontSecondary;
|
||||
if (theme.fonts.font_family.primary) {
|
||||
fontPrimary = theme.fonts.font_family.primary
|
||||
.replace(/\+/g, " ")
|
||||
.replace(/:[ital,]*[ital@]*[wght@]*[0-9,;.]+/gi, "");
|
||||
.replace(/:[ital,]*[ital@]*[wght@]*[0-9,;]+/gi, "");
|
||||
}
|
||||
if (theme.fonts.font_family.secondary) {
|
||||
fontSecondary = theme.fonts.font_family.secondary
|
||||
.replace(/\+/g, " ")
|
||||
.replace(/:[ital,]*[ital@]*[wght@]*[0-9,;.]+/gi, "");
|
||||
.replace(/:[ital,]*[ital@]*[wght@]*[0-9,;]+/gi, "");
|
||||
}
|
||||
|
||||
// types for frontmatters
|
||||
@@ -34,15 +34,16 @@ export interface Props {
|
||||
image?: string;
|
||||
noindex?: boolean;
|
||||
canonical?: string;
|
||||
lang?: string;
|
||||
}
|
||||
|
||||
// destructure frontmatter
|
||||
const { title, meta_title, description, image, noindex, canonical } =
|
||||
// distructure frontmatters
|
||||
const { title, meta_title, description, image, noindex, canonical, lang } =
|
||||
Astro.props;
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html lang={lang}>
|
||||
<head>
|
||||
<!-- favicon -->
|
||||
<link rel="shortcut icon" href={config.site.favicon} />
|
||||
@@ -107,7 +108,7 @@ const { title, meta_title, description, image, noindex, canonical } =
|
||||
<meta
|
||||
name="description"
|
||||
content={plainify(
|
||||
description ? description : config.metadata.meta_description
|
||||
description ? description : config.metadata.meta_description,
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -120,7 +121,7 @@ const { title, meta_title, description, image, noindex, canonical } =
|
||||
<meta
|
||||
property="og:title"
|
||||
content={plainify(
|
||||
meta_title ? meta_title : title ? title : config.site.title
|
||||
meta_title ? meta_title : title ? title : config.site.title,
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -128,7 +129,7 @@ const { title, meta_title, description, image, noindex, canonical } =
|
||||
<meta
|
||||
property="og:description"
|
||||
content={plainify(
|
||||
description ? description : config.metadata.meta_description
|
||||
description ? description : config.metadata.meta_description,
|
||||
)}
|
||||
/>
|
||||
<meta property="og:type" content="website" />
|
||||
@@ -141,7 +142,7 @@ const { title, meta_title, description, image, noindex, canonical } =
|
||||
<meta
|
||||
name="twitter:title"
|
||||
content={plainify(
|
||||
meta_title ? meta_title : title ? title : config.site.title
|
||||
meta_title ? meta_title : title ? title : config.site.title,
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -149,7 +150,7 @@ const { title, meta_title, description, image, noindex, canonical } =
|
||||
<meta
|
||||
name="twitter:description"
|
||||
content={plainify(
|
||||
description ? description : config.metadata.meta_description
|
||||
description ? description : config.metadata.meta_description,
|
||||
)}
|
||||
/>
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import ImageMod from "./components/ImageMod.astro";
|
||||
|
||||
const COLLECTION_FOLDER = "blog";
|
||||
const { post } = Astro.props;
|
||||
const { lang } = Astro.params;
|
||||
|
||||
const posts = await getSinglePage(COLLECTION_FOLDER);
|
||||
const similarPosts = similarItems(post, posts);
|
||||
@@ -39,7 +40,7 @@ const { title, description, author, categories, image, date, tags } = post.data;
|
||||
<h1 set:html={markdownify(title)} class="h2 mb-4" />
|
||||
<ul class="mb-4">
|
||||
<li class="mr-4 inline-block">
|
||||
<a href={`/authors/${slugify(author)}`}>
|
||||
<a href={`/${lang === "en" ? "authors" + "/" : lang}/authors/${slugify(author)}`} >
|
||||
<FaRegUserCircle className={"mr-2 -mt-1 inline-block"} />
|
||||
{humanize(author)}
|
||||
</a>
|
||||
@@ -48,7 +49,9 @@ const { title, description, author, categories, image, date, tags } = post.data;
|
||||
<FaRegFolder className={"mr-2 -mt-1 inline-block"} />
|
||||
{
|
||||
categories.map((category: string, index: number) => (
|
||||
<a href={`/categories/${slugify(category)}`}>
|
||||
<a
|
||||
href={`/${lang === "en" ? "categories" + "/" : lang}/categories/${slugify(category)}`}
|
||||
>
|
||||
{humanize(category)}
|
||||
{index !== categories.length - 1 && ","}
|
||||
</a>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
---
|
||||
import { getLangFromUrl } from "@/lib/utils/i18nUtils";
|
||||
import { plainify } from "@/lib/utils/textConverter";
|
||||
import ImageMod from "./ImageMod.astro";
|
||||
import Social from "./Social.astro";
|
||||
|
||||
const { data } = Astro.props;
|
||||
const { title, image, social } = data.data;
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
---
|
||||
|
||||
<div
|
||||
@@ -23,7 +25,9 @@ const { title, image, social } = data.data;
|
||||
)
|
||||
}
|
||||
<h4 class="mb-3">
|
||||
<a href={`/authors/${data.slug}`}>{title}</a>
|
||||
<a href={`/${lang === "en" ? "authors" + "/" : lang}/${data.slug}`}
|
||||
>{title}</a
|
||||
>
|
||||
</h4>
|
||||
<p class="mb-4">
|
||||
{plainify(data.body?.slice(0, 100))}
|
||||
|
||||
@@ -4,6 +4,7 @@ import dateFormat from "@/lib/utils/dateFormat";
|
||||
import { humanize, plainify, slugify } from "@/lib/utils/textConverter";
|
||||
import { FaRegFolder, FaRegUserCircle } from "react-icons/fa";
|
||||
import ImageMod from "./ImageMod.astro";
|
||||
import { getLangFromUrl } from "@/lib/utils/i18nUtils";
|
||||
|
||||
const {
|
||||
summary_length,
|
||||
@@ -11,6 +12,9 @@ const {
|
||||
}: { summary_length: number; blog_folder: string } = config.settings;
|
||||
const { data } = Astro.props;
|
||||
const { title, image, date, author, categories } = data.data;
|
||||
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
const path = Astro.url.pathname;
|
||||
---
|
||||
|
||||
<div class="bg-body dark:bg-darkmode-body">
|
||||
@@ -27,13 +31,17 @@ const { title, image, date, author, categories } = data.data;
|
||||
)
|
||||
}
|
||||
<h4 class="mb-3">
|
||||
<a href={`/${blog_folder}/${data.slug}`}>
|
||||
<a
|
||||
href={path.includes("/categories")
|
||||
? `/${lang === "en" ? "/" : lang}/blog/${data.slug}`
|
||||
: `/${lang === "en" ? "/" : lang}/${data.slug}`}
|
||||
>
|
||||
{title}
|
||||
</a>
|
||||
</h4>
|
||||
<ul class="mb-4">
|
||||
<li class="mr-4 inline-block">
|
||||
<a href={`/authors/${slugify(author)}`}>
|
||||
<a href={`/${lang}/authors/${slugify(author)}`}>
|
||||
<FaRegUserCircle className={"mr-2 -mt-1 inline-block"} />
|
||||
{humanize(author)}
|
||||
</a>
|
||||
@@ -42,7 +50,7 @@ const { title, image, date, author, categories } = data.data;
|
||||
<FaRegFolder className={"mr-2 -mt-1 inline-block"} />
|
||||
{
|
||||
categories.map((category: string, index: number) => (
|
||||
<a href={`/categories/${slugify(category)}`}>
|
||||
<a href={`/${lang}/categories/${slugify(category)}`}>
|
||||
{humanize(category)}
|
||||
{index !== categories.length - 1 && ","}
|
||||
</a>
|
||||
@@ -54,7 +62,9 @@ const { title, image, date, author, categories } = data.data;
|
||||
<p class="mb-6">{plainify(data.body?.slice(0, Number(summary_length)))}</p>
|
||||
<a
|
||||
class="btn btn-outline-primary btn-sm"
|
||||
href={`/${blog_folder}/${data.slug}`}
|
||||
href={path.includes("/categories")
|
||||
? `/${lang === "en" ? "/" : lang}/blog/${data.slug}`
|
||||
: `/${lang === "en" ? "/" : lang}/${data.slug}`}
|
||||
>
|
||||
read more
|
||||
</a>
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
---
|
||||
import { getLangFromUrl } from "@/lib/utils/i18nUtils";
|
||||
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
|
||||
type Pagination = {
|
||||
section?: string;
|
||||
currentPage?: number;
|
||||
totalPages?: number;
|
||||
};
|
||||
const { section, currentPage = 1, totalPages = 1 }: Pagination = Astro.props;
|
||||
const {
|
||||
section,
|
||||
currentPage = 1,
|
||||
totalPages = 1
|
||||
}: Pagination = Astro.props;
|
||||
|
||||
const indexPageLink = currentPage === 2;
|
||||
const hasPrevPage = currentPage > 1;
|
||||
@@ -27,8 +35,8 @@ for (let i = 1; i <= totalPages; i++) {
|
||||
<a
|
||||
href={
|
||||
indexPageLink
|
||||
? `${section ? "/" + section : "/"}`
|
||||
: `${section ? "/" + section : ""}/page/${currentPage - 1}`
|
||||
? `/${lang}/${section ? section : ""}`
|
||||
: `/${lang}/${section ? section : ""}/page/${currentPage - 1}`
|
||||
}
|
||||
class="rounded px-2 py-1.5 text-dark hover:bg-theme-light dark:text-darkmode-dark dark:hover:bg-darkmode-theme-light"
|
||||
>
|
||||
@@ -79,8 +87,8 @@ for (let i = 1; i <= totalPages; i++) {
|
||||
<a
|
||||
href={
|
||||
i === 0
|
||||
? `${section ? "/" + section : "/"}`
|
||||
: `${section ? "/" + section : ""}/page/${pagination}`
|
||||
? `/${lang}/${section ? section : ""}`
|
||||
: `/${lang}/${section ? section : ""}/page/${pagination}`
|
||||
}
|
||||
aria-current="page"
|
||||
class="rounded px-4 py-2 text-dark hover:bg-theme-light dark:text-darkmode-dark dark:hover:bg-darkmode-theme-light"
|
||||
@@ -93,7 +101,7 @@ for (let i = 1; i <= totalPages; i++) {
|
||||
{/* next page */}
|
||||
{hasNextPage ? (
|
||||
<a
|
||||
href={`${section ? "/" + section : ""}/page/${currentPage + 1}`}
|
||||
href={`/${lang}/${section ? section : ""}/page/${currentPage + 1}`}
|
||||
class="rounded px-2 py-1.5 text-dark hover:bg-theme-light dark:text-darkmode-dark dark:hover:bg-darkmode-theme-light"
|
||||
>
|
||||
<span class="sr-only">Next</span>
|
||||
@@ -132,3 +140,4 @@ for (let i = 1; i <= totalPages; i++) {
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,24 +2,17 @@
|
||||
import Logo from "@/components/Logo.astro";
|
||||
import ThemeSwitcher from "@/components/ThemeSwitcher.astro";
|
||||
import config from "@/config/config.json";
|
||||
import menu from "@/config/menu.json";
|
||||
import { getLangFromUrl, languages, useTranslations } from "@/lib/utils/i18nUtils";
|
||||
import { loadMenu } from "@/lib/utils/loadMenu";
|
||||
import { getRelativeLocaleUrl } from "astro:i18n";
|
||||
import { IoSearch } from "react-icons/io5";
|
||||
|
||||
export interface ChildNavigationLink {
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface NavigationLink {
|
||||
name: string;
|
||||
url: string;
|
||||
hasChildren?: boolean;
|
||||
children?: ChildNavigationLink[];
|
||||
}
|
||||
|
||||
const { main }: { main: NavigationLink[] } = menu;
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
const menu = loadMenu(lang);
|
||||
const { navigation_button, settings } = config;
|
||||
const { pathname } = Astro.url;
|
||||
|
||||
const t = useTranslations(lang as any);
|
||||
---
|
||||
|
||||
<header class={`header z-30 ${settings.sticky_header && "sticky top-0"}`}>
|
||||
@@ -46,20 +39,23 @@ const { pathname } = Astro.url;
|
||||
</svg>
|
||||
</label>
|
||||
<!-- /navbar toggler -->
|
||||
|
||||
<ul
|
||||
id="nav-menu"
|
||||
class="navbar-nav order-3 hidden w-full pb-6 lg:order-1 lg:flex lg:w-auto lg:space-x-2 lg:pb-0 xl:space-x-8"
|
||||
>
|
||||
{
|
||||
main.map((menu) => (
|
||||
menu.main.map((menu: any) => (
|
||||
<>
|
||||
{menu.hasChildren ? (
|
||||
<li class="nav-item nav-dropdown group relative">
|
||||
<span
|
||||
class={`nav-link inline-flex items-center ${
|
||||
menu.children?.map(({ url }) => url).includes(pathname) ||
|
||||
menu.children
|
||||
?.map(({ url }) => `${url}/`)
|
||||
?.map(({ url }: { url: any }) => url)
|
||||
.includes(pathname) ||
|
||||
menu.children
|
||||
?.map(({ url }: { url: any }) => `${url}/`)
|
||||
.includes(pathname)
|
||||
? "active"
|
||||
: ""
|
||||
@@ -71,10 +67,10 @@ const { pathname } = Astro.url;
|
||||
</svg>
|
||||
</span>
|
||||
<ul class="nav-dropdown-list hidden group-hover:block lg:invisible lg:absolute lg:block lg:opacity-0 lg:group-hover:visible lg:group-hover:opacity-100">
|
||||
{menu.children?.map((child) => (
|
||||
{menu.children?.map((child: any) => (
|
||||
<li class="nav-dropdown-item">
|
||||
<a
|
||||
href={child.url}
|
||||
href={getRelativeLocaleUrl(lang, child.url)}
|
||||
aria-label={child.name}
|
||||
class={`nav-dropdown-link block ${
|
||||
(pathname === `${child.url}/` ||
|
||||
@@ -91,7 +87,7 @@ const { pathname } = Astro.url;
|
||||
) : (
|
||||
<li class="nav-item">
|
||||
<a
|
||||
href={menu.url}
|
||||
href={getRelativeLocaleUrl(lang, menu.url)}
|
||||
class={`nav-link block ${
|
||||
(pathname === `${menu.url}/` || pathname === menu.url) &&
|
||||
"active"
|
||||
@@ -104,6 +100,7 @@ const { pathname } = Astro.url;
|
||||
</>
|
||||
))
|
||||
}
|
||||
|
||||
{
|
||||
navigation_button.enable && (
|
||||
<li class="mt-4 inline-block lg:hidden">
|
||||
@@ -111,13 +108,58 @@ const { pathname } = Astro.url;
|
||||
class="btn btn-outline-primary btn-sm"
|
||||
href={navigation_button.link}
|
||||
>
|
||||
{navigation_button.label}
|
||||
{t('get_started')}
|
||||
</a>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
</ul>
|
||||
|
||||
<div class="order-1 ml-auto flex items-center md:order-2 lg:ml-0">
|
||||
<!-- Language dropdown -->
|
||||
<div class="nav-item nav-dropdown group relative border mr-5">
|
||||
<span
|
||||
class={`nav-link inline-flex items-center ${
|
||||
languages
|
||||
.map((child) => getRelativeLocaleUrl(child, "/"))
|
||||
.includes(pathname)
|
||||
? "active"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
{lang}
|
||||
<svg class="h-4 w-4 fill-current" viewBox="0 0 20 20">
|
||||
<path
|
||||
d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"
|
||||
></path>
|
||||
</svg>
|
||||
</span>
|
||||
<ul
|
||||
class="nav-dropdown-list hidden group-hover:block lg:invisible lg:absolute lg:block lg:opacity-0 lg:group-hover:visible lg:group-hover:opacity-100"
|
||||
>
|
||||
{
|
||||
languages.map((child: string) => (
|
||||
<li class="nav-dropdown-item">
|
||||
<a
|
||||
href={
|
||||
child === "en"
|
||||
? pathname.replace(`/${lang}`, "")
|
||||
: `/${child}${pathname.replace(`/${lang}`, "")}`
|
||||
}
|
||||
aria-label={child}
|
||||
class={`nav-dropdown-link block ${
|
||||
pathname.startsWith(`/${child}`) && "active"
|
||||
}`}
|
||||
>
|
||||
{child}
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
<!-- End Language dropdown -->
|
||||
|
||||
{
|
||||
settings.search && (
|
||||
<button
|
||||
@@ -136,7 +178,7 @@ const { pathname } = Astro.url;
|
||||
class="btn btn-outline-primary btn-sm hidden lg:inline-block"
|
||||
href={navigation_button.link}
|
||||
>
|
||||
{navigation_button.label}
|
||||
{t('get_started')}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,16 +1,56 @@
|
||||
---
|
||||
// import {
|
||||
// getCollection,
|
||||
// type CollectionEntry,
|
||||
// type CollectionKey,
|
||||
// } from "astro:content";
|
||||
|
||||
// export const getSinglePage = async <C extends CollectionKey>(
|
||||
// collectionName: C,
|
||||
// ): Promise<CollectionEntry<C>[]> => {
|
||||
// const allPages = await getCollection(collectionName);
|
||||
// const removeIndex = allPages.filter((data) => data.id.match(/^(?!-)/));
|
||||
// const removeDrafts = removeIndex.filter((data) => !data.data.draft);
|
||||
// return removeDrafts;
|
||||
// };
|
||||
|
||||
import {
|
||||
getCollection,
|
||||
type CollectionEntry,
|
||||
type CollectionKey,
|
||||
type ContentEntryMap,
|
||||
} from "astro:content";
|
||||
|
||||
import config from "@/config/config.json";
|
||||
|
||||
export const getSinglePage = async <C extends CollectionKey>(
|
||||
collectionName: C,
|
||||
lang: keyof ContentEntryMap
|
||||
): Promise<CollectionEntry<C>[]> => {
|
||||
const allPages = await getCollection(collectionName);
|
||||
const removeIndex = allPages.filter((data) => data.id.match(/^(?!-)/));
|
||||
const removeDrafts = removeIndex.filter((data) => !data.data.draft);
|
||||
const { defaultLang } = config.language;
|
||||
const langCollection: keyof ContentEntryMap = lang as keyof ContentEntryMap;
|
||||
|
||||
// Explicitly define the type of pages to CollectionEntry<C>[]
|
||||
const pages: CollectionEntry<C>[] = await getCollection(langCollection || defaultLang, ({ id }) => {
|
||||
return id.startsWith(collectionName) && !id.endsWith("-index.md");
|
||||
}) as CollectionEntry<C>[];
|
||||
|
||||
const removeDrafts = pages.filter((data) => !data.data.draft);
|
||||
return removeDrafts;
|
||||
};
|
||||
|
||||
|
||||
export const getListPage = async <C extends CollectionKey>(
|
||||
collectionName: C,
|
||||
lang: keyof ContentEntryMap
|
||||
): Promise<CollectionEntry<C>[]> => {
|
||||
const { defaultLang } = config.language;
|
||||
const langCollection: keyof ContentEntryMap = lang as keyof ContentEntryMap;
|
||||
// Fetch the collection based on the language
|
||||
const pages: CollectionEntry<C>[] = await getCollection(langCollection || defaultLang, ({ id }) => {
|
||||
return id.startsWith(collectionName);
|
||||
}) as CollectionEntry<C>[];
|
||||
|
||||
return pages;
|
||||
};
|
||||
---
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
---
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { slugify } from "@/lib/utils/textConverter";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
|
||||
// get taxonomy from frontmatter
|
||||
export const getTaxonomy = async (collection: any, name: string) => {
|
||||
const singlePages = await getSinglePage(collection);
|
||||
// const singlePages = await getSinglePage(collection);
|
||||
const singlePages = await getCollection(
|
||||
collection as keyof ContentEntryMap,
|
||||
({ id }) => {
|
||||
return id.startsWith("blog") && !id.endsWith("-index.md");
|
||||
}
|
||||
);
|
||||
const taxonomyPages = singlePages.map((page: any) => page.data[name]);
|
||||
let taxonomies: string[] = [];
|
||||
for (let i = 0; i < taxonomyPages.length; i++) {
|
||||
@@ -19,7 +28,13 @@ export const getTaxonomy = async (collection: any, name: string) => {
|
||||
|
||||
// get all taxonomies from frontmatter
|
||||
export const getAllTaxonomy = async (collection: any, name: string) => {
|
||||
const singlePages = await getSinglePage(collection);
|
||||
// const singlePages = await getSinglePage(collection);
|
||||
const singlePages = await getCollection(
|
||||
collection as keyof ContentEntryMap,
|
||||
({ id }) => {
|
||||
return id.startsWith("blog") && !id.endsWith("-index.md");
|
||||
}
|
||||
);
|
||||
const taxonomyPages = singlePages.map((page: any) => page.data[name]);
|
||||
let taxonomies: string[] = [];
|
||||
for (let i = 0; i < taxonomyPages.length; i++) {
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const menusFolderPath = './src/config';
|
||||
|
||||
const locales = fs.readdirSync(menusFolderPath)
|
||||
.filter(file => /^menu\.[a-z]{2}\.json$/.test(file))
|
||||
.map(file => {
|
||||
const filePath = path.join(menusFolderPath, file);
|
||||
const localeName = file.split('.')[1]; // Extract language code from file name
|
||||
const localeData = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||||
return { [localeName]: localeData };
|
||||
})
|
||||
.reduce((accumulator, locale) => {
|
||||
return { ...accumulator, ...locale };
|
||||
}, {});
|
||||
|
||||
// Extract all languages from the locales object
|
||||
const languages = Object.keys(locales);
|
||||
|
||||
// Export the locales and languages
|
||||
export { locales, languages };
|
||||
|
||||
export function getLangFromUrl(url: URL): string {
|
||||
const [, lang] = url.pathname.split('/');
|
||||
if (locales.hasOwnProperty(lang)) {
|
||||
return lang;
|
||||
}
|
||||
return 'en';
|
||||
}
|
||||
|
||||
|
||||
|
||||
// import { ui } from '@/i18n/ui';
|
||||
// import config from "@/config/config.json";
|
||||
// const {defaultLang}: {defaultLang : keyof typeof ui} = config.language as any;
|
||||
|
||||
// export function useTranslations(lang: keyof typeof ui) {
|
||||
// return function t(key: keyof typeof ui[typeof defaultLang]) {
|
||||
// return ui[lang][key] || ui[defaultLang][key];
|
||||
// }
|
||||
// }
|
||||
|
||||
import { ui } from '@/i18n/ui';
|
||||
import config from "@/config/config.json";
|
||||
|
||||
const { defaultLang }: { defaultLang: keyof typeof ui } = config.language as any;
|
||||
|
||||
export function useTranslations(lang?: keyof typeof ui) {
|
||||
const activeLang = lang || defaultLang;
|
||||
|
||||
return function t(key: keyof typeof ui[typeof defaultLang]): string {
|
||||
const translation = ui[activeLang][key];
|
||||
|
||||
// If not found, fall back to the default language
|
||||
if (translation) {
|
||||
return translation;
|
||||
} else {
|
||||
return ui[defaultLang][key];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export interface ChildNavigationLink {
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface NavigationLink {
|
||||
name: string;
|
||||
url: string;
|
||||
hasChildren?: boolean;
|
||||
children?: ChildNavigationLink[];
|
||||
}
|
||||
|
||||
interface Menu {
|
||||
main: NavigationLink[];
|
||||
footer: NavigationLink[];
|
||||
}
|
||||
|
||||
export function loadMenu(lang: string): Menu {
|
||||
const menuPath: string = path.join(process.cwd(), 'src', 'config', `menu.${lang}.json`);
|
||||
const menuData: string = fs.readFileSync(menuPath, 'utf-8');
|
||||
return JSON.parse(menuData) as Menu;
|
||||
}
|
||||
+16
-6
@@ -1,5 +1,18 @@
|
||||
---
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import config from "@/config/config.json";
|
||||
import { getLangFromUrl, useTranslations } from "@/lib/utils/i18nUtils";
|
||||
|
||||
export function getStaticPaths() {
|
||||
const {supported} = config.language;
|
||||
const paths = supported.map((lang) => ({ params: { lang: lang || undefined } }));
|
||||
return paths;
|
||||
}
|
||||
|
||||
const lang = getLangFromUrl(Astro.url);
|
||||
const t = useTranslations(lang as any);
|
||||
const {defaultLang} = config.language;
|
||||
const href = lang && lang !== defaultLang ? `/${lang}/` : "/";
|
||||
---
|
||||
|
||||
<Base title="Page Not Found">
|
||||
@@ -12,14 +25,11 @@ import Base from "@/layouts/Base.astro";
|
||||
>
|
||||
404
|
||||
</span>
|
||||
<h1 class="h2 mb-4">Page not found</h1>
|
||||
<h1 class="h2 mb-4">{t("page_not_found")}</h1>
|
||||
<div class="content">
|
||||
<p>
|
||||
The page you are looking for might have been removed, had its name
|
||||
changed, or is temporarily unavailable.
|
||||
</p>
|
||||
<p>{t("page_not_found_content")}</p>
|
||||
</div>
|
||||
<a href="/" class="btn btn-primary mt-8">Back to home</a>
|
||||
<a href={href} class="btn btn-primary mt-8">{t("back_to_home")}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
---
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
|
||||
// get static paths for all pages
|
||||
export async function getStaticPaths() {
|
||||
const COLLECTION_FOLDER = "pages";
|
||||
const { supported } = config.language;
|
||||
|
||||
const pages = await getSinglePage(COLLECTION_FOLDER);
|
||||
const paths = await Promise.all(
|
||||
supported.map(async (lang) => {
|
||||
const pages = await getSinglePage("pages", lang as keyof ContentEntryMap);
|
||||
|
||||
const paths = pages.map((page) => ({
|
||||
params: {
|
||||
regular: page.slug,
|
||||
},
|
||||
props: { page },
|
||||
}));
|
||||
return paths;
|
||||
return pages.map((page) => ({
|
||||
params: {
|
||||
lang: lang || undefined,
|
||||
regular: page.slug.split("/").pop(),
|
||||
},
|
||||
props: {
|
||||
page,
|
||||
},
|
||||
}));
|
||||
})
|
||||
);
|
||||
return paths.flat();
|
||||
}
|
||||
|
||||
const { page } = Astro.props;
|
||||
@@ -2,11 +2,22 @@
|
||||
import ImageMod from "@/components/ImageMod.astro";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { markdownify } from "@/lib/utils/textConverter";
|
||||
import { getEntry } from "astro:content";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { getCollection } from "astro:content";
|
||||
import config from "@/config/config.json";
|
||||
import { getListPage } from "@/lib/contentParser.astro";
|
||||
|
||||
const about = await getEntry("about", "-index");
|
||||
const { Content } = await about.render();
|
||||
const { title, description, meta_title, image } = about.data;
|
||||
export function getStaticPaths() {
|
||||
const {supported} = config.language;
|
||||
const paths = supported.map((lang) => ({ params: { lang: lang || undefined } }));
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { lang } = Astro.params;
|
||||
const about = await getListPage("about", lang as keyof ContentEntryMap);
|
||||
|
||||
const { Content } = await about[0].render();
|
||||
const { title, description, meta_title, image } = about[0].data;
|
||||
---
|
||||
|
||||
<Base
|
||||
@@ -2,33 +2,46 @@
|
||||
import BlogCard from "@/components/BlogCard.astro";
|
||||
import ImageMod from "@/components/ImageMod.astro";
|
||||
import Social from "@/components/Social.astro";
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { slugify } from "@/lib/utils/textConverter";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
// get all static paths for authors
|
||||
export async function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
const COLLECTION_FOLDER = "authors";
|
||||
const authors = await getSinglePage(COLLECTION_FOLDER);
|
||||
|
||||
const paths = authors.map((author) => ({
|
||||
params: {
|
||||
single: author.slug,
|
||||
},
|
||||
props: { author },
|
||||
}));
|
||||
return paths;
|
||||
const paths = await Promise.all(
|
||||
supported.map(async (lang) => {
|
||||
const authors = await getSinglePage(COLLECTION_FOLDER, lang as keyof ContentEntryMap);
|
||||
|
||||
return authors.map((author) => ({
|
||||
params: {
|
||||
lang: lang || undefined,
|
||||
single: author.slug.split("/").pop(),
|
||||
},
|
||||
props: {
|
||||
author,
|
||||
lang
|
||||
},
|
||||
}));
|
||||
})
|
||||
);
|
||||
return paths.flat();
|
||||
}
|
||||
|
||||
const { author } = Astro.props;
|
||||
const { author, lang } = Astro.props;
|
||||
const { title, social, meta_title, description, image } = author.data;
|
||||
const { Content } = await author.render();
|
||||
|
||||
// get all posts by author
|
||||
const BLOG_FOLDER = "blog";
|
||||
const posts = await getSinglePage(BLOG_FOLDER);
|
||||
const posts = await getSinglePage(BLOG_FOLDER, lang as keyof ContentEntryMap);
|
||||
const postFilterByAuthor = posts.filter(
|
||||
(post) => slugify(post.data.author) === slugify(title),
|
||||
(post) => slugify(post.data.author) === slugify(title)
|
||||
);
|
||||
---
|
||||
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
---
|
||||
import AuthorCard from "@/components/AuthorCard.astro";
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getListPage, getSinglePage } from "@/lib/contentParser.astro";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import { type ContentEntryMap } from "astro:content";
|
||||
|
||||
const COLLECTION_FOLDER = "authors";
|
||||
|
||||
export function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
const paths = supported.map((lang) => ({
|
||||
params: { lang: lang || undefined },
|
||||
}));
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { lang } = Astro.params;
|
||||
const authorIndex = await getListPage(
|
||||
COLLECTION_FOLDER,
|
||||
lang as keyof ContentEntryMap
|
||||
);
|
||||
const authors = await getSinglePage(
|
||||
COLLECTION_FOLDER,
|
||||
lang as keyof ContentEntryMap
|
||||
);
|
||||
---
|
||||
|
||||
<Base title={authorIndex[0].data.title}>
|
||||
<PageHeader title={authorIndex[0].data.title} />
|
||||
<section class="section-sm pb-0">
|
||||
<div class="container">
|
||||
<div class="row justify-center">
|
||||
{
|
||||
authors.map((author) => (
|
||||
<div class="mb-14 md:col-6 lg:col-4">
|
||||
<AuthorCard data={author} />
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
---
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import PostSingle from "@/layouts/PostSingle.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
const BLOG_FOLDER = "blog";
|
||||
|
||||
const paths = await Promise.all(
|
||||
supported.map(async (lang) => {
|
||||
const posts = await getSinglePage(BLOG_FOLDER, lang as keyof ContentEntryMap);
|
||||
|
||||
return posts.map((post) => ({
|
||||
params: {
|
||||
lang: lang || undefined,
|
||||
single: post.slug.split("/").pop(),
|
||||
},
|
||||
props: {
|
||||
post,
|
||||
},
|
||||
}));
|
||||
})
|
||||
);
|
||||
return paths.flat();
|
||||
}
|
||||
|
||||
const { post } = Astro.props;
|
||||
const { title, meta_title, description, image } = post.data;
|
||||
---
|
||||
<Base
|
||||
title={title}
|
||||
meta_title={meta_title}
|
||||
description={description}
|
||||
image={image}
|
||||
>
|
||||
<PostSingle post={post} />
|
||||
</Base>
|
||||
@@ -3,32 +3,43 @@ import BlogCard from "@/components/BlogCard.astro";
|
||||
import Pagination from "@/components/Pagination.astro";
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { getListPage, getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { getAllTaxonomy, getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { sortByDate } from "@/lib/utils/sortFunctions";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import PostSidebar from "@/partials/PostSidebar.astro";
|
||||
import { getEntry } from "astro:content";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
|
||||
export function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
const paths = supported.map((lang) => ({
|
||||
params: { lang: lang || undefined },
|
||||
}));
|
||||
return paths;
|
||||
}
|
||||
const { lang } = Astro.params;
|
||||
const BLOG_FOLDER = "blog";
|
||||
// const postIndex = await getListPage(BLOG_FOLDER, lang as keyof ContentEntryMap);
|
||||
const postIndex: any
|
||||
= await getListPage(BLOG_FOLDER, lang as keyof ContentEntryMap);
|
||||
const langCollection: keyof ContentEntryMap = lang as keyof ContentEntryMap;
|
||||
const posts = await getSinglePage(BLOG_FOLDER, lang as keyof ContentEntryMap);
|
||||
|
||||
const postIndex = await getEntry(BLOG_FOLDER, "-index");
|
||||
const posts = await getSinglePage(BLOG_FOLDER);
|
||||
const allCategories = await getAllTaxonomy(BLOG_FOLDER, "categories");
|
||||
const categories = await getTaxonomy(BLOG_FOLDER, "categories");
|
||||
const tags = await getTaxonomy(BLOG_FOLDER, "tags");
|
||||
const allCategories = await getAllTaxonomy(langCollection, "categories");
|
||||
const categories = await getTaxonomy(langCollection, "categories");
|
||||
const tags = await getTaxonomy(langCollection, "tags");
|
||||
const sortedPosts = sortByDate(posts);
|
||||
const totalPages: number = Math.ceil(posts.length / config.settings.pagination);
|
||||
const currentPosts = sortedPosts.slice(0, config.settings.pagination);
|
||||
---
|
||||
|
||||
<Base
|
||||
title={postIndex.data.title}
|
||||
meta_title={postIndex.data.meta_title}
|
||||
image={postIndex.data.image}
|
||||
description={postIndex.data.description}
|
||||
title={postIndex[0].data.title}
|
||||
meta_title={postIndex[0].data.meta_title}
|
||||
image={postIndex[0].data.image}
|
||||
description={postIndex[0].data.description}
|
||||
>
|
||||
<PageHeader title={postIndex.data.title} />
|
||||
<PageHeader title={postIndex[0].data.title} />
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="row gx-5">
|
||||
@@ -3,21 +3,32 @@ import BlogCard from "@/components/BlogCard.astro";
|
||||
import Pagination from "@/components/Pagination.astro";
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { getAllTaxonomy, getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { sortByDate } from "@/lib/utils/sortFunctions";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import PostSidebar from "@/partials/PostSidebar.astro";
|
||||
import { getEntry } from "astro:content";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
const BLOG_FOLDER = "blog";
|
||||
|
||||
const { slug } = Astro.params;
|
||||
const postIndex = await getEntry(BLOG_FOLDER, "-index");
|
||||
const posts = await getSinglePage(BLOG_FOLDER);
|
||||
const allCategories = await getAllTaxonomy(BLOG_FOLDER, "categories");
|
||||
const categories = await getTaxonomy(BLOG_FOLDER, "categories");
|
||||
const tags = await getTaxonomy(BLOG_FOLDER, "tags");
|
||||
const { slug, lang } = Astro.params;
|
||||
|
||||
const postIndex = await getCollection(
|
||||
lang as keyof ContentEntryMap,
|
||||
({ id }) => {
|
||||
return id.startsWith(BLOG_FOLDER);
|
||||
}
|
||||
);
|
||||
|
||||
const posts = await getCollection(lang as keyof ContentEntryMap, ({ id }) => {
|
||||
return id.startsWith(BLOG_FOLDER) && !id.endsWith("-index.md");
|
||||
});
|
||||
|
||||
const langCollection: keyof ContentEntryMap = lang as keyof ContentEntryMap;
|
||||
const allCategories = await getAllTaxonomy(langCollection, "categories");
|
||||
const categories = await getTaxonomy(langCollection, "categories");
|
||||
const tags = await getTaxonomy(langCollection, "tags");
|
||||
const sortedPosts = sortByDate(posts);
|
||||
const totalPages = Math.ceil(posts.length / config.settings.pagination);
|
||||
const currentPage = slug && !isNaN(Number(slug)) ? Number(slug) : 1;
|
||||
@@ -26,29 +37,46 @@ const indexOfFirstPost = indexOfLastPost - config.settings.pagination;
|
||||
const currentPosts = sortedPosts.slice(indexOfFirstPost, indexOfLastPost);
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
const BLOG_FOLDER = "blog";
|
||||
const posts = await getSinglePage(BLOG_FOLDER);
|
||||
const totalPages = Math.ceil(posts.length / config.settings.pagination);
|
||||
const paths = [];
|
||||
|
||||
for (let i = 1; i < totalPages; i++) {
|
||||
paths.push({
|
||||
params: {
|
||||
slug: (i + 1).toString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
return paths;
|
||||
const paths = await Promise.all(
|
||||
supported.map(async (lang) => {
|
||||
const posts = await getCollection(
|
||||
lang as keyof ContentEntryMap,
|
||||
({ id }) => {
|
||||
return id.startsWith(BLOG_FOLDER) && !id.endsWith("-index.md");
|
||||
}
|
||||
);
|
||||
|
||||
const totalPages = Math.ceil(posts.length / config.settings.pagination);
|
||||
const langString = lang.toString();
|
||||
const langPaths = [];
|
||||
|
||||
for (let i = 1; i < totalPages; i++) {
|
||||
langPaths.push({
|
||||
params: {
|
||||
lang: langString,
|
||||
slug: (i + 1).toString(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return langPaths;
|
||||
})
|
||||
);
|
||||
|
||||
return paths.flat();
|
||||
}
|
||||
---
|
||||
|
||||
<Base
|
||||
title={postIndex.data.title}
|
||||
meta_title={postIndex.data.meta_title}
|
||||
image={postIndex.data.image}
|
||||
description={postIndex.data.description}
|
||||
title={postIndex[0].data.title}
|
||||
meta_title={postIndex[0].data.meta_title}
|
||||
image={postIndex[0].data.image}
|
||||
description={postIndex[0].data.description}
|
||||
>
|
||||
<PageHeader title={postIndex.data.title} />
|
||||
<PageHeader title={postIndex[0].data.title} />
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="row gx-5">
|
||||
+21
-10
@@ -1,5 +1,6 @@
|
||||
---
|
||||
import BlogCard from "@/components/BlogCard.astro";
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
@@ -7,23 +8,33 @@ import { sortByDate } from "@/lib/utils/sortFunctions";
|
||||
import taxonomyFilter from "@/lib/utils/taxonomyFilter";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
|
||||
// get static paths for all categories
|
||||
// get all static paths for categories
|
||||
export async function getStaticPaths() {
|
||||
const BLOG_FOLDER = "blog";
|
||||
const categories = await getTaxonomy(BLOG_FOLDER, "categories");
|
||||
const { supported } = config.language;
|
||||
|
||||
return categories.map((category) => {
|
||||
return {
|
||||
params: { category },
|
||||
};
|
||||
});
|
||||
const paths = await Promise.all(
|
||||
supported.map(async (lang) => {
|
||||
const categories = await getTaxonomy(lang, "categories");
|
||||
|
||||
return categories.map((category) => ({
|
||||
params: {
|
||||
lang: lang || undefined,
|
||||
category: category,
|
||||
},
|
||||
props: {
|
||||
category,
|
||||
},
|
||||
}));
|
||||
})
|
||||
);
|
||||
return paths.flat();
|
||||
}
|
||||
|
||||
const { category } = Astro.params;
|
||||
const { category, lang } = Astro.params;
|
||||
|
||||
// get posts by category
|
||||
const BLOG_FOLDER = "blog";
|
||||
const posts = await getSinglePage(BLOG_FOLDER);
|
||||
const posts = await getSinglePage(BLOG_FOLDER, lang as any);
|
||||
const filterByCategories = taxonomyFilter(posts, "categories", category!);
|
||||
const sortedPosts = sortByDate(filterByCategories);
|
||||
---
|
||||
@@ -3,11 +3,19 @@ import Base from "@/layouts/Base.astro";
|
||||
import { getAllTaxonomy, getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { humanize } from "@/lib/utils/textConverter";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import config from "@/config/config.json";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
|
||||
const BLOG_FOLDER = "blog";
|
||||
export function getStaticPaths() {
|
||||
const {supported } = config.language;
|
||||
const paths = supported.map((lang) => ({ params: { lang: lang || undefined } }));
|
||||
return paths;
|
||||
}
|
||||
|
||||
const categories = await getTaxonomy(BLOG_FOLDER, "categories");
|
||||
const allCategories = await getAllTaxonomy(BLOG_FOLDER, "categories");
|
||||
const { lang } = Astro.params;
|
||||
const langCollection: keyof ContentEntryMap = lang as keyof ContentEntryMap;
|
||||
const categories = await getTaxonomy(langCollection, "categories");
|
||||
const allCategories = await getAllTaxonomy(langCollection, "categories");
|
||||
---
|
||||
|
||||
<Base title={"Categories"}>
|
||||
@@ -21,7 +29,7 @@ const allCategories = await getAllTaxonomy(BLOG_FOLDER, "categories");
|
||||
return (
|
||||
<li class="m-3 inline-block">
|
||||
<a
|
||||
href={`/categories/${category}`}
|
||||
href={`/${lang === "en" ? "categories" + "/" : lang}/categories/${category}`}
|
||||
class="block rounded bg-theme-light px-4 py-2 text-xl text-dark dark:bg-darkmode-theme-light dark:text-darkmode-dark"
|
||||
>
|
||||
{humanize(category)}{" "}
|
||||
@@ -1,12 +1,24 @@
|
||||
---
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getListPage } from "@/lib/contentParser.astro";
|
||||
import { useTranslations } from "@/lib/utils/i18nUtils";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import { getEntry } from "astro:content";
|
||||
import { type ContentEntryMap } from "astro:content";
|
||||
|
||||
export function getStaticPaths() {
|
||||
const {supported} = config.language;
|
||||
const paths = supported.map((lang) => ({ params: { lang: lang || undefined } }));
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { lang } = Astro.params;
|
||||
const contact = await getListPage("contact", lang as keyof ContentEntryMap);
|
||||
|
||||
const contact = await getEntry("contact", "-index");
|
||||
const { contact_form_action }: { contact_form_action: string } = config.params;
|
||||
const { title, description, meta_title, image } = contact.data;
|
||||
const { title, description, meta_title, image } = contact[0].data;
|
||||
|
||||
const t = useTranslations(lang as any);
|
||||
---
|
||||
|
||||
<Base
|
||||
@@ -23,7 +35,8 @@ const { title, description, meta_title, image } = contact.data;
|
||||
<form action={contact_form_action} method="POST">
|
||||
<div class="mb-6">
|
||||
<label for="name" class="form-label">
|
||||
Full Name <span class="text-red-500">*</span>
|
||||
{t("full_name")}
|
||||
<span class="text-red-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
id="name"
|
||||
@@ -35,7 +48,7 @@ const { title, description, meta_title, image } = contact.data;
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<label for="email" class="form-label">
|
||||
Working Mail <span class="text-red-500">*</span>
|
||||
{t("working_mail")} <span class="text-red-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
id="email"
|
||||
@@ -47,16 +60,16 @@ const { title, description, meta_title, image } = contact.data;
|
||||
</div>
|
||||
<div class="mb-6">
|
||||
<label for="message" class="form-label">
|
||||
Anything else? <span class="text-red-500">*</span>
|
||||
{t("anything_else")} <span class="text-red-500">*</span>
|
||||
</label>
|
||||
<textarea
|
||||
id="message"
|
||||
name="message"
|
||||
class="form-input"
|
||||
placeholder="Message goes here..."
|
||||
placeholder={t("contact_message_placeholder")}
|
||||
rows="8"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
<button type="submit" class="btn btn-primary">{t("submit")}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,12 +1,16 @@
|
||||
---
|
||||
import ImageMod from "@/components/ImageMod.astro";
|
||||
import config from "@/config/config.json";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getListPage } from "@/lib/contentParser.astro";
|
||||
import { markdownify } from "@/lib/utils/textConverter";
|
||||
import CallToAction from "@/partials/CallToAction.astro";
|
||||
import Testimonial from "@/partials/Testimonial.astro";
|
||||
import type { Button, Feature } from "@/types";
|
||||
import { getEntry } from "astro:content";
|
||||
import type { ContentEntryMap } from "astro:content";
|
||||
import { getCollection } from "astro:content";
|
||||
import { FaCheck } from "react-icons/fa";
|
||||
const { defaultLang } = config.language;
|
||||
|
||||
interface Homepage {
|
||||
banner: {
|
||||
@@ -18,10 +22,35 @@ interface Homepage {
|
||||
features: Feature[];
|
||||
}
|
||||
|
||||
const homepage = await getEntry("homepage", "-index");
|
||||
const testimonial = await getEntry("sections", "testimonial");
|
||||
const call_to_action = await getEntry("sections", "call-to-action");
|
||||
const { banner, features }: Homepage = homepage.data;
|
||||
export function getStaticPaths() {
|
||||
const { supported } = config.language;
|
||||
const paths = supported.map((lang) => ({
|
||||
params: { lang: lang || undefined },
|
||||
}));
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { lang } = Astro.params;
|
||||
const homepage = await getListPage("homepage", lang as keyof ContentEntryMap);
|
||||
|
||||
// const testimonial = await getEntry("sections", "testimonial");
|
||||
// const call_to_action = await getEntry("sections", "call-to-action");
|
||||
const { banner, features }: Homepage = homepage[0].data;
|
||||
|
||||
const testimonial = await getCollection(
|
||||
(lang as keyof ContentEntryMap) || defaultLang,
|
||||
({ id }) => {
|
||||
return id.startsWith("sections/testimonial") && !id.endsWith("-index.md");
|
||||
}
|
||||
);
|
||||
const call_to_action = await getCollection(
|
||||
(lang as keyof ContentEntryMap) || defaultLang,
|
||||
({ id }) => {
|
||||
return (
|
||||
id.startsWith("sections/call-to-action") && !id.endsWith("-index.md")
|
||||
);
|
||||
}
|
||||
);
|
||||
---
|
||||
|
||||
<Base>
|
||||
@@ -109,6 +138,6 @@ const { banner, features }: Homepage = homepage.data;
|
||||
}
|
||||
<!-- /Features -->
|
||||
|
||||
<Testimonial testimonial={testimonial} />
|
||||
<CallToAction call_to_action={call_to_action} />
|
||||
<Testimonial testimonial={testimonial[0]} />
|
||||
<CallToAction call_to_action={call_to_action[0]} />
|
||||
</Base>
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
import AuthorCard from "@/components/AuthorCard.astro";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
import { getEntry } from "astro:content";
|
||||
|
||||
const COLLECTION_FOLDER = "authors";
|
||||
|
||||
const authorIndex = await getEntry(COLLECTION_FOLDER, "-index");
|
||||
const authors = await getSinglePage(COLLECTION_FOLDER);
|
||||
---
|
||||
|
||||
<Base title={authorIndex.data.title}>
|
||||
<PageHeader title={authorIndex.data.title} />
|
||||
<section class="section-sm pb-0">
|
||||
<div class="container">
|
||||
<div class="row justify-center">
|
||||
{
|
||||
authors.map((author) => (
|
||||
<div class="mb-14 md:col-6 lg:col-4">
|
||||
<AuthorCard data={author} />
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import PostSingle from "@/layouts/PostSingle.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const BLOG_FOLDER = "blog";
|
||||
const posts = await getSinglePage(BLOG_FOLDER);
|
||||
|
||||
const paths = posts.map((post) => ({
|
||||
params: {
|
||||
single: post.slug,
|
||||
},
|
||||
props: { post },
|
||||
}));
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { post } = Astro.props;
|
||||
const { title, meta_title, description, image } = post.data;
|
||||
---
|
||||
|
||||
<Base
|
||||
title={title}
|
||||
meta_title={meta_title}
|
||||
description={description}
|
||||
image={image}
|
||||
>
|
||||
<PostSingle post={post} />
|
||||
</Base>
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
import BlogCard from "@/components/BlogCard.astro";
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getSinglePage } from "@/lib/contentParser.astro";
|
||||
import { getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { sortByDate } from "@/lib/utils/sortFunctions";
|
||||
import taxonomyFilter from "@/lib/utils/taxonomyFilter";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const BLOG_FOLDER = "blog";
|
||||
const tags = await getTaxonomy(BLOG_FOLDER, "tags");
|
||||
|
||||
return tags.map((tag) => {
|
||||
return {
|
||||
params: { tag },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const { tag } = Astro.params;
|
||||
|
||||
// get posts by tag
|
||||
const BLOG_FOLDER = "blog";
|
||||
const posts = await getSinglePage(BLOG_FOLDER);
|
||||
const filterByTags = taxonomyFilter(posts, "tags", tag!);
|
||||
const sortedPosts = sortByDate(filterByTags);
|
||||
---
|
||||
|
||||
<Base title={tag}>
|
||||
<PageHeader title={tag} />
|
||||
<div class="section-sm pb-0">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
{
|
||||
sortedPosts.map((post) => (
|
||||
<div class="mb-14 md:col-6 lg:col-4">
|
||||
<BlogCard data={post} />
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Base>
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import { getAllTaxonomy, getTaxonomy } from "@/lib/taxonomyParser.astro";
|
||||
import { humanize } from "@/lib/utils/textConverter";
|
||||
import PageHeader from "@/partials/PageHeader.astro";
|
||||
|
||||
const BLOG_FOLDER = "blog";
|
||||
|
||||
const tags = await getTaxonomy(BLOG_FOLDER, "tags");
|
||||
const allTags = await getAllTaxonomy(BLOG_FOLDER, "tags");
|
||||
---
|
||||
|
||||
<Base title={"Tags"}>
|
||||
<PageHeader title={"Tags"} />
|
||||
<section class="section">
|
||||
<div class="container text-center">
|
||||
<ul>
|
||||
{
|
||||
tags.map((tag: any) => {
|
||||
const count = allTags.filter((c) => c === tag).length;
|
||||
return (
|
||||
<li class="m-3 inline-block">
|
||||
<a
|
||||
href={`/tags/${tag}`}
|
||||
class="block rounded bg-theme-light px-4 py-2 text-xl text-dark dark:bg-darkmode-theme-light dark:text-darkmode-dark"
|
||||
>
|
||||
{humanize(tag)}{" "}
|
||||
<span class="ml-2 rounded bg-body px-2 dark:bg-darkmode-body">
|
||||
{count}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
@@ -3,7 +3,7 @@ html {
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-body text-base dark:bg-darkmode-body font-primary font-normal leading-relaxed text-text dark:text-darkmode-text;
|
||||
@apply bg-body dark:bg-darkmode-body font-primary font-normal leading-relaxed text-text dark:text-darkmode-text;
|
||||
}
|
||||
|
||||
h1,
|
||||
|
||||
Reference in New Issue
Block a user