دلوقتي انا بحاول ارفع مشروع ويب سايت علي جت هب كنت...
创建于:2025年8月26日
使用 GPT-5 Thinking 回答 Chat01
创建于:2025年8月26日
使用 GPT-5 Thinking 回答 Chat01
دلوقتي انا بحاول ارفع مشروع ويب سايت علي جت هب كنت عامله من تمبلت هبعتلك الاخطاء الي جاتلي في الاكشن وانت لو احتاجت اي بيانات قولي
واخر حاجه كانت علي تريمنال اهي
Yousef@Apples-MacBook-Pro my-portfolio % nano _includes/layouts/base.njk
Yousef@Apples-MacBook-Pro my-portfolio % npm i -D @11ty/eleventy-navigation
up to date, audited 230 packages in 4s
45 packages are looking for funding
run npm fund
for details
1 moderate severity vulnerability
To address all issues (including breaking changes), run:
npm audit fix --force
Run npm audit
for details.
Yousef@Apples-MacBook-Pro my-portfolio % nano .eleventy.js
Yousef@Apples-MacBook-Pro my-portfolio % grep -n "{% *comment" 404.md || echo "OK: no comment blocks"
OK: no comment blocks
Yousef@Apples-MacBook-Pro my-portfolio % grep -n "{% *endcomment" 404.md || echo "OK: no endcomment blocks"
OK: no endcomment blocks
Yousef@Apples-MacBook-Pro my-portfolio % npx @11ty/eleventy --version
npx @11ty/eleventy
git add -A
git commit -m "Enable @11ty/eleventy-navigation and clean Nunjucks comments"
git push origin main
2.0.1
[11ty] Writing _site/sitemap.xml from ./sitemap.xml.njk
[11ty] Writing _site/feed/feed.xml from ./feed/feed.njk
[11ty] Writing _site/feed/.htaccess from ./feed/htaccess.njk
[11ty] Writing _site/projects/concept-dystopian-city/index.html from ./projects/concept-dystopian-city.md (njk)
[11ty] Writing _site/about/index.html from ./about/index.md (njk)
[11ty] Writing _site/posts/bandmember/index.html from ./posts/bandmember.md (njk)
[11ty] Writing _site/posts/chef/index.html from ./posts/chef.md (njk)
[11ty] Writing _site/posts/firstpost/index.html from ./posts/firstpost.md (njk)
[11ty] Writing _site/posts/secondpost/index.html from ./posts/secondpost.md (njk)
[11ty] Writing _site/posts/fourthpost/index.html from ./posts/fourthpost.md (njk)
[11ty] Writing _site/posts/sailboat/index.html from ./posts/sailboat.md (njk)
[11ty] Writing _site/posts/thirdpost/index.html from ./posts/thirdpost.md (njk)
[11ty] Writing _site/posts/p6/index.html from ./posts/p6.md (njk)
[11ty] Writing _site/posts/wedding/index.html from ./posts/wedding.md (njk)
[11ty] Writing _site/posts/underwater/index.html from ./posts/underwater.md (njk)
[11ty] Writing _site/posts/wedding2/index.html from ./posts/wedding2.md (njk)
[11ty] Writing _site/posts/rocks/index.html from ./posts/rocks.md (njk)
[11ty] Writing _site/404.html from ./404.md (njk)
[11ty] Writing _site/contact/index.html from ./contact.njk
[11ty] Writing _site/posts/index.html from ./archive.njk
[11ty] Writing _site/page-list/index.html from ./page-list.njk
[11ty] Writing _site/page-list/1/index.html from ./page-list.njk
[11ty] Writing _site/page-list/2/index.html from ./page-list.njk
[11ty] Writing _site/page-list/3/index.html from ./page-list.njk
[11ty] Writing _site/index.html from ./index.njk
[11ty] Writing _site/photos/index.html from ./photos.njk
[11ty] Writing _site/projects/index.html from ./projects.njk
[11ty] Writing _site/tags/index.html from ./tags-list.njk
[11ty] Writing _site/tags/project/index.html from ./tags.njk
[11ty] Writing _site/tags/notphoto/index.html from ./tags.njk
[11ty] Writing _site/tags/photo/index.html from ./tags.njk
[11ty] Writing _site/tags/another-tag/index.html from ./tags.njk
[11ty] Writing _site/tags/number-2/index.html from ./tags.njk
[11ty] Writing _site/tags/second-tag/index.html from ./tags.njk
[11ty] Writing _site/projects/concept-art/index.html from ./projects/concept-art.njk
[11ty] Writing _site/projects/graphic-design/index.html from ./projects/graphic-design.njk
[11ty] Writing _site/projects/short-film-projects/index.html from ./projects/short-film-projects.njk
[11ty] Writing _site/projects/concept-art-concept00/index.html from ./projects/concept-art-concept00.md (njk)
[11ty] Writing _site/projects/concept-art-concept02/index.html from ./projects/concept-art-concept02.md (njk)
[11ty] Writing _site/projects/concept-art-concept01/index.html from ./projects/concept-art-concept01.md (njk)
[11ty] Writing _site/projects/concept-art-concept03/index.html from ./projects/concept-art-concept03.md (njk)
[11ty] Writing _site/projects/concept-art-concept04/index.html from ./projects/concept-art-concept04.md (njk)
[11ty] Writing _site/projects/concept-art-concept05/index.html from ./projects/concept-art-concept05.md (njk)
[11ty] Writing _site/projects/concept-art-concept06/index.html from ./projects/concept-art-concept06.md (njk)
[11ty] Writing _site/projects/concept-art-concept07/index.html from ./projects/concept-art-concept07.md (njk)
[11ty] Writing _site/projects/concept-art-concept08/index.html from ./projects/concept-art-concept08.md (njk)
[11ty] Writing _site/projects/concept-art-concept09/index.html from ./projects/concept-art-concept09.md (njk)
[11ty] Writing _site/projects/concept-art-concept10/index.html from ./projects/concept-art-concept10.md (njk)
[11ty] Writing _site/projects/concept-art-concept11/index.html from ./projects/concept-art-concept11.md (njk)
[11ty] Writing _site/projects/concept-art-concept12/index.html from ./projects/concept-art-concept12.md (njk)
[11ty] Writing _site/projects/concept-art-concept13/index.html from ./projects/concept-art-concept13.md (njk)
[11ty] Writing _site/projects/concept-art-concept16/index.html from ./projects/concept-art-concept16.md (njk)
[11ty] Writing _site/projects/concept-art-concept14/index.html from ./projects/concept-art-concept14.md (njk)
[11ty] Writing _site/projects/concept-art-concept15/index.html from ./projects/concept-art-concept15.md (njk)
[11ty] Writing _site/projects/concept-art-concept17/index.html from ./projects/concept-art-concept17.md (njk)
[11ty] Writing _site/projects/concept-art-concept19/index.html from ./projects/concept-art-concept19.md (njk)
[11ty] Writing _site/projects/concept-art-concept18/index.html from ./projects/concept-art-concept18.md (njk)
[11ty] Writing _site/projects/concept-art-concept20/index.html from ./projects/concept-art-concept20.md (njk)
[11ty] Writing _site/projects/concept-art-concept21/index.html from ./projects/concept-art-concept21.md (njk)
[11ty] Writing _site/projects/graphic-design-poster01/index.html from ./projects/graphic-design-poster01.md (njk)
[11ty] Writing _site/projects/graphic-design-poster02/index.html from ./projects/graphic-design-poster02.md (njk)
[11ty] Writing _site/projects/graphic-design-poster03/index.html from ./projects/graphic-design-poster03.md (njk)
[11ty] Writing _site/projects/graphic-design-poster04/index.html from ./projects/graphic-design-poster04.md (njk)
[11ty] Writing _site/projects/graphic-design-poster05/index.html from ./projects/graphic-design-poster05.md (njk)
[11ty] Writing _site/projects/graphic-design-poster06/index.html from ./projects/graphic-design-poster06.md (njk)
[11ty] Writing _site/projects/graphic-design-poster07/index.html from ./projects/graphic-design-poster07.md (njk)
[11ty] Writing _site/projects/graphic-design-poster08/index.html from ./projects/graphic-design-poster08.md (njk)
[11ty] Writing _site/projects/graphic-design-poster11/index.html from ./projects/graphic-design-poster11.md (njk)
[11ty] Writing _site/projects/graphic-design-poster09/index.html from ./projects/graphic-design-poster09.md (njk)
[11ty] Writing _site/projects/graphic-design-poster10/index.html from ./projects/graphic-design-poster10.md (njk)
[11ty] Writing _site/projects/graphic-design-poster12/index.html from ./projects/graphic-design-poster12.md (njk)
[11ty] Writing _site/projects/graphic-design-poster13/index.html from ./projects/graphic-design-poster13.md (njk)
[11ty] Writing _site/projects/graphic-design-poster14/index.html from ./projects/graphic-design-poster14.md (njk)
[11ty] Writing _site/projects/graphic-design-poster15/index.html from ./projects/graphic-design-poster15.md (njk)
[11ty] Writing _site/projects/short-film-AdmiralpredictaTV/index.html from ./projects/short-film-AdmiralpredictaTV.md (njk)
[11ty] Writing _site/projects/short-film-CaricatureAyaAraffa/index.html from ./projects/short-film-CaricatureAyaAraffa.md (njk)
[11ty] Writing _site/projects/short-film-GazaUprooted/index.html from ./projects/short-film-GazaUprooted.md (njk)
[11ty] Writing _site/projects/short-film-Palestineisfree/index.html from ./projects/short-film-Palestineisfree.md (njk)
[11ty] Writing _site/projects/short-film-PhilcoVintage/index.html from ./projects/short-film-PhilcoVintage.md (njk)
[11ty] Writing _site/projects/short-film-TVseriesmodels/index.html from ./projects/short-film-TVseriesmodels.md (njk)
[11ty] Writing _site/projects/short-film-Seaofworries/index.html from ./projects/short-film-Seaofworries.md (njk)
[11ty] Writing _site/projects/short-film-TortureWaiter/index.html from ./projects/short-film-TortureWaiter.md (njk)
[11ty] Copied 67 files / Wrote 82 files in 0.80 seconds (9.8ms each, v2.0.1)
[main 62054a5] Enable @11ty/eleventy-navigation and clean Nunjucks comments
1 file changed, 1 insertion(+), 1 deletion(-)
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 334 bytes | 334.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To https://github.com/YousefMohamd/YousefMohamd.github.io.git
a19ebe7..62054a5 main -> main
Yousef@Apples-MacBook-Pro my-portfolio %
تمام يا يوسف 👌 واضح إن عندك مشكلتين كانوا حاصلين:
github-pages
❌.خلّيني أمشي معاك خطوة بخطوة علشان النشر يشتغل من main
من غير Errors.
أنت عملت npm i -D @11ty/eleventy-navigation
وبنيت محليًا بنجاح—تمام. اتأكد إنك مضيف البلجن في .eleventy.js
:
js// .eleventy.js const eleventyNavigation = require("@11ty/eleventy-navigation"); module.exports = function(eleventyConfig) { eleventyConfig.addPlugin(eleventyNavigation); return { dir: { input: ".", output: "_site" } }; };
مهم في CI: ما تخليش الـ workflow يثبّت dependencies من غير devDependencies. استخدم npm ci
عادي وبدون --production
أو NODE_ENV=production
.
لو عندك خطوة بتعمل npm ci --omit=dev
أو مهيّأ NODE_ENV=production
، شيلها.
(بديلًا: ممكن تنقل @11ty/eleventy-navigation
من devDependencies لـ dependencies، بس الأفضل تسيبه dev وتثبّت devDeps في البيلد.)
الرسالة دي جاية من بيئة اسمها github-pages
اتعملت تلقائيًا. غالبًا متظبطة إنها تسمح بـ “Selected branches” ومش مضافة فيها main
، أو فيها “Required reviewers”.
اعمل الآتي في الريبو على GitHub:
Settings → Environments → github-pages → Edit
main
.Settings → Pages
بعد كده أي push على main
هيعدّي الحماية وهيكمّل نشر Pages.
لو عايز أبسط وأحدث إعداد، استخدم الـ Actions الرسمية لـ Pages. أنشئ/حدّث الملف:
.github/workflows/deploy.yml
yamlname: Deploy Eleventy to Pages on: push: branches: [ "main" ] workflow_dispatch: permissions: contents: read pages: write id-token: write concurrency: group: "pages" cancel-in-progress: true jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 cache: npm # مهم: تثبيت devDependencies - run: npm ci # بنبني الموقع إلى _site - run: npx @11ty/eleventy # نرفع الأرتيفاكت بتاع _site للنشر - uses: actions/upload-pages-artifact@v3 with: path: _site deploy: needs: build runs-on: ubuntu-latest environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment uses: actions/deploy-pages@v4
ده بيعمل:
main
._site
كـ artifact.github-pages
.gh-pages
برانش)لو عايز تنشر على برانش gh-pages
بدل بيئة github-pages
:
peaceiris/actions-gh-pages
لدفع محتوى _site
إلى gh-pages
. (بس بصراحة الحل الرسمي فوق أنضف وأسهل.).eleventy.js
فيه addPlugin(eleventyNavigation)
package.json
: مفيش --omit=dev
في CI (أو انقل البلجن لـ dependencies)main
أو “All branches”، وألغِ/وافق على Required reviewersnpm ci
و npx @11ty/eleventy
و deploy-pages
لو حابب، ابعتلي محتوى ملف الـ workflow الحالي .github/workflows/*.yml
و/أو صورة من إعدادات Environment github-pages
، وأنا أظبّطهولك سطر بسطر.
خطا جديد Run actions/jekyll-build-pages@v1
/usr/bin/docker run --name ghcrioactionsjekyllbuildpagesv1013_95cc3b --label 0154b0 --workdir /github/workspace --rm -e "INPUT_SOURCE" -e "INPUT_DESTINATION" -e "INPUT_FUTURE" -e "INPUT_BUILD_REVISION" -e "INPUT_VERBOSE" -e "INPUT_TOKEN" -e "HOME" -e "GITHUB_JOB" -e "GITHUB_REF" -e "GITHUB_SHA" -e "GITHUB_REPOSITORY" -e "GITHUB_REPOSITORY_OWNER" -e "GITHUB_REPOSITORY_OWNER_ID" -e "GITHUB_RUN_ID" -e "GITHUB_RUN_NUMBER" -e "GITHUB_RETENTION_DAYS" -e "GITHUB_RUN_ATTEMPT" -e "GITHUB_ACTOR_ID" -e "GITHUB_ACTOR" -e "GITHUB_WORKFLOW" -e "GITHUB_HEAD_REF" -e "GITHUB_BASE_REF" -e "GITHUB_EVENT_NAME" -e "GITHUB_SERVER_URL" -e "GITHUB_API_URL" -e "GITHUB_GRAPHQL_URL" -e "GITHUB_REF_NAME" -e "GITHUB_REF_PROTECTED" -e "GITHUB_REF_TYPE" -e "GITHUB_WORKFLOW_REF" -e "GITHUB_WORKFLOW_SHA" -e "GITHUB_REPOSITORY_ID" -e "GITHUB_TRIGGERING_ACTOR" -e "GITHUB_WORKSPACE" -e "GITHUB_ACTION" -e "GITHUB_EVENT_PATH" -e "GITHUB_ACTION_REPOSITORY" -e "GITHUB_ACTION_REF" -e "GITHUB_PATH" -e "GITHUB_ENV" -e "GITHUB_STEP_SUMMARY" -e "GITHUB_STATE" -e "GITHUB_OUTPUT" -e "RUNNER_OS" -e "RUNNER_ARCH" -e "RUNNER_NAME" -e "RUNNER_ENVIRONMENT" -e "RUNNER_TOOL_CACHE" -e "RUNNER_TEMP" -e "RUNNER_WORKSPACE" -e "ACTIONS_RUNTIME_URL" -e "ACTIONS_RUNTIME_TOKEN" -e "ACTIONS_CACHE_URL" -e "ACTIONS_ID_TOKEN_REQUEST_URL" -e "ACTIONS_ID_TOKEN_REQUEST_TOKEN" -e "ACTIONS_RESULTS_URL" -e GITHUB_ACTIONS=true -e CI=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" -v "/home/runner/work/_temp/_runner_file_commands":"/github/file_commands" -v "/home/runner/work/YousefMohamd.github.io/YousefMohamd.github.io":"/github/workspace" ghcr.io/actions/jekyll-build-pages:v1.0.13
Configuration file: none
To use retry middleware with Faraday v2.0+, install faraday-retry
gem
Build Warning: Layout 'layouts/home.njk' requested in 404.md does not exist.
Liquid Exception: Liquid syntax error (line 3): Unknown tag 'set' in archive.njk
/usr/local/bundle/gems/liquid-4.0.4/lib/liquid/document.rb:23:in unknown_tag': Liquid syntax error (line 3): Unknown tag 'set' (Liquid::SyntaxError) from /usr/local/bundle/gems/liquid-4.0.4/lib/liquid/document.rb:11:in
block in parse'
from /usr/local/bundle/gems/liquid-4.0.4/lib/liquid/block_body.rb:32:in parse' from /usr/local/bundle/gems/liquid-4.0.4/lib/liquid/document.rb:10:in
parse'
from /usr/local/bundle/gems/liquid-4.0.4/lib/liquid/document.rb:5:in parse' from /usr/local/bundle/gems/liquid-4.0.4/lib/liquid/template.rb:130:in
parse'
from /usr/local/bundle/gems/liquid-4.0.4/lib/liquid/template.rb:114:in parse' from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/liquid_renderer/file.rb:13:in
block in parse'
from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/liquid_renderer/file.rb:49:in measure_time' from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/liquid_renderer/file.rb:12:in
parse'
from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/renderer.rb:121:in render_liquid' from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/renderer.rb:79:in
render_document'
from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/renderer.rb:62:in run' from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/site.rb:479:in
render_regenerated'
from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/site.rb:472:in block in render_pages' from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/site.rb:471:in
each'
from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/site.rb:471:in render_pages' from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/site.rb:192:in
render'
from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/site.rb:71:in process' from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/command.rb:28:in
process_site'
from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/commands/build.rb:65:in build' from /usr/local/bundle/gems/jekyll-3.10.0/lib/jekyll/commands/build.rb:36:in
process'
from /usr/local/bundle/gems/github-pages-232/bin/github-pages:70:in block (3 levels) in <top (required)>' from /usr/local/bundle/gems/mercenary-0.3.6/lib/mercenary/command.rb:220:in
block in execute'
from /usr/local/bundle/gems/mercenary-0.3.6/lib/mercenary/command.rb:220:in each' from /usr/local/bundle/gems/mercenary-0.3.6/lib/mercenary/command.rb:220:in
execute'
from /usr/local/bundle/gems/mercenary-0.3.6/lib/mercenary/program.rb:42:in go' from /usr/local/bundle/gems/mercenary-0.3.6/lib/mercenary.rb:19:in
program'
from /usr/local/bundle/gems/github-pages-232/bin/github-pages:6:in <top (required)>' from /usr/local/bundle/bin/github-pages:25:in
load'
from /usr/local/bundle/bin/github-pages:25:in `<main>'
Error: Logging at level: debug GitHub Pages: github-pages v232 GitHub Pages: jekyll v3.10.0 Theme: jekyll-theme-primer Theme source: /usr/local/bundle/gems/jekyll-theme-primer-0.6.0 Requiring: jekyll-github-metadata Requiring: jekyll-seo-tag Requiring: jekyll-coffeescript Requiring: jekyll-commonmark-ghpages Requiring: jekyll-gist Requiring: jekyll-github-metadata Requiring: jekyll-paginate Requiring: jekyll-relative-links Requiring: jekyll-optional-front-matter Requiring: jekyll-readme-index Requiring: jekyll-default-layout Requiring: jekyll-titles-from-headings GitHub Metadata: Initializing... Source: /github/workspace/. Destination: /github/workspace/./_site Incremental build: disabled. Enable with --incremental Generating... Generating: JekyllOptionalFrontMatter::Generator finished in 0.000187832 seconds. Generating: JekyllReadmeIndex::Generator finished in 0.006775583 seconds. Generating: Jekyll::Paginate::Pagination finished in 4.709e-06 seconds. Generating: JekyllRelativeLinks::Generator finished in 0.002221334 seconds. Generating: JekyllDefaultLayout::Generator finished in 0.000946885 seconds. Requiring: kramdown-parser-gfm Generating: JekyllTitlesFromHeadings::Generator finished in 0.00785727 seconds. Rendering: 404.md Pre-Render Hooks: 404.md Rendering Liquid: 404.md Rendering Markup: 404.md Rendering Layout: 404.md Rendering: archive.njk Pre-Render Hooks: archive.njk Rendering Liquid: archive.njk github-pages 232 | Error: Liquid syntax error (line 3): Unknown tag 'set'
تمام—الخطأ ده سببه إن الـ Workflow بتاعك بيشغّل Jekyll (actions/jekyll-build-pages@v1
) بينما مشروعك Eleventy (Nunjucks). جِت هب بيحاول يفسّر ملفات .njk
بـ Liquid، فبيطلع: Unknown tag 'set'
. الحل: شيل Jekyll من الـ workflow، وخلّي النشر يتم عن طريق Build بـ Node → رفع الـ artifact → Deploy Pages.
.github/workflows/
فيه jekyll-build-pages
أو اسمه زي jekyll.yml
/ pages.yml
منテンبلت جِت هب الافتراضي.أنشئ ملف: .github/workflows/deploy.yml
بالمحتوى ده:
yamlname: Deploy Eleventy to Pages on: push: branches: [ "main" ] workflow_dispatch: permissions: contents: read pages: write id-token: write concurrency: group: "pages" cancel-in-progress: true jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 cache: 'npm' # مهم: تثبيت الـ devDependencies (علشان البلجن eleventy-navigation) - run: npm ci # Build Eleventy إلى مجلد _site - run: npx @11ty/eleventy # تهيئة Pages (اختياري لكنه مفضل) - uses: actions/configure-pages@v5 # ارفع ناتج البيلد للنشر - uses: actions/upload-pages-artifact@v3 with: path: _site deploy: needs: build runs-on: ubuntu-latest environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} steps: - id: deployment uses: actions/deploy-pages@v4
github-pages
→ Edit
main
ضمن Selected branches.لو حابب بسرعة من الترمينال:
bashgit rm .github/workflows/jekyll.yml 2>/dev/null || true git add .github/workflows/deploy.yml git commit -m "Switch from Jekyll to Eleventy Pages workflow" git push origin main
Layout 'layouts/home.njk' does not exist
جي من Jekyll، وهيروح لما نبطل نبني بـ Jekyll. (محليًا Eleventy عندك كان بيبني 404 بنجاح بالفعل.)npm ci --omit=dev
أو NODE_ENV=production
بيمنع devDeps: شيلها، لأن @11ty/eleventy-navigation
عندك devDependency.جرّب الخطوات دي، وهتلاقي الـ Action الجديد بيظهر Jobين: build و deploy — من غير سطر actions/jekyll-build-pages@v1
. لو حبيت تبعتلي محتوى أي Workflow قديم علشان أنضّفهولك، ابعته وأنا أعدّلهولك فورًا.
في خبر سعيد الموقع اشتغل جرب كده https://yousefmohamd.github.io/
جامد جدًا يا يوسف! 🎉 الموقع شغّال وبيفتح تمام عندي، والقوايم (Home / About / Projects / Photos / Contact / Archive) ظاهرة كويس، وكمان صفحة الـ About و Projects و Archive شغّالة. (yousefmohamd.github.io)
index.njk
علشان الشكل يطلع أنضف. (yousefmohamd.github.io)website: YousefMohamed.com
—لو لسه ما عندكش دومين مخصص، بدّله لـ https://yousefmohamd.github.io/
أو سيبه فاضي. وبرضه في سطر “Age: 21 years ago”؛ الأفضل تكتب سنة الميلاد أو تشيله خالص. (yousefmohamd.github.io)loading="lazy"
في <img>
لتحسين الأداء.<meta name="description">
ووسوم Open Graph/Twitter علشان المشاركة على السوشيال تبقى مرتّبة.لو حابب أبعتلك PR صغير يشيل سطر الـ “DEBUG”، يحدّث لينك الـ CV، ويشيل لينك الـ Archive من الناف—قولّي وابعتهولك على طول. 🙌
واحده واحده كده اديني اوامر عشان الغي ال
DEBUG from index.njk
وكمان في حاجات اما فتحت الموقع من الموبايل ظهرلي ايكونز كنت شايلها من التمبلت اصلا زي الارشيف دي والفوتوز اشيلهم ازاي وكمان
الصور مش اوبتومايز وبتاخد وقت في التحميل وساعات مبتحملش
حل كل ده باحترافيه
جامد يا يوسف! نِظّبطها واحدة واحدة زي ما طلبت—هنشيل سطر الـ DEBUG، نخفي روابط/أيقونات Archive و Photos من المينيو (خصوصًا على الموبايل)، وبعدين نعمل Optimizations احترافية للصور عشان تبقى سريعة وما تقعّش.
DEBUG from index.njk
لو أنت على الماك، نفّذ ده في جذر المشروع (أبسط طريقة):
bash# احذف أي سطر فيه "DEBUG from index.njk" من الصفحة الرئيسية sed -i '' '/DEBUG from index\.njk/d' index.njk git add index.njk git commit -m "Remove debug line from index.njk" git push origin main
(لو السطر في مكان تاني، استخدم grep -Rn "DEBUG from index.njk" .
عشان تلاقيه.)
الروابط دي بتيجي من Eleventy Navigation؛ أسهل حل إننا نخلّي الصفحات موجودة بس متظهرش في الناف.
hidden: true
في الـ front matter للصفحاتافتح كل صفحة عايز تخبيها (زي archive.njk
و photos.njk
) وحط hidden: true
جوه بلوك الـ navigation:
archive.njk
(مثال):
yaml--- layout: layouts/base.njk title: Archive eleventyNavigation: key: Archive order: 9 hidden: true ---
photos.njk
(مثال):
yaml--- layout: layouts/base.njk title: Photos eleventyNavigation: key: Photos order: 4 hidden: true ---
بعد التعديل:
bashgit add archive.njk photos.njk git commit -m "Hide Archive & Photos from nav via eleventyNavigation.hidden" git push origin main
لو عايز تمنع ظهور أي عناصر غير اللي أنت محددها (حتى لو حد نسي يشيلها من الصفحات)، عدّل جزء بناء القائمة في /_includes/layouts/base.njk
(أو ملف الهيدر اللي فيه اللوب بتاع الناف):
njk{# قبل اللوب مباشرة #} {% set allowed = ["Home", "About", "Projects", "Contact", "CV"] %} {% set nav = collections.all | eleventyNavigation %} <ul class="site-nav"> {% for item in nav %} {% if item.key in allowed %} <li><a href="{{ item.url | url }}">{{ item.title or item.key }}</a></li> {% endif %} {% endfor %} </ul>
كده حتى على الموبايل، أيقونات أو عناصر جاية من الناف مش هتظهر غير لو اسمها ضمن
allowed
.
bashnpm i -D @11ty/eleventy-img
عدّل ملف .eleventy.js
:
jsconst eleventyNavigation = require("@11ty/eleventy-navigation"); const Image = require("@11ty/eleventy-img"); async function imageShortcode(src, alt = "", sizes = "(max-width: 900px) 100vw, 900px") { if (!alt) { throw new Error(`Missing ALT for image: ${src}`); } let metadata = await Image(src, { widths: [320, 640, 900, 1200, 1600], formats: ["avif", "webp", "jpeg"], outputDir: "_site/img/", urlPath: "/img/", sharpJpeg: { quality: 78, mozjpeg: true }, sharpWebp: { quality: 74 }, sharpAvif: { quality: 60 }, cacheOptions: { // كاش بين البيلدات لتسريع CI duration: "1y", } }); const imageAttributes = { alt, sizes, loading: "lazy", // مهم للأداء decoding: "async" // يقلل الـ main-thread work }; return Image.generateHTML(metadata, imageAttributes, { whitespaceMode: "inline" }); } module.exports = function (eleventyConfig) { eleventyConfig.addPlugin(eleventyNavigation); // Shortcodes لكل المحركات eleventyConfig.addNunjucksAsyncShortcode("img", imageShortcode); eleventyConfig.addLiquidShortcode("img", (src, alt, sizes) => imageShortcode(src, alt, sizes)); eleventyConfig.addJavaScriptFunction("img", imageShortcode); return { dir: { input: ".", output: "_site" } }; };
<img>
العادية بالـ shortcodeافتح الصفحات اللي فيها صور كتير (خصوصًا index.njk
وملفات المشاريع) واستبدل:
html<!-- القديم --> <img src="/images/hero.jpg" alt="Yousef hero"> <!-- الجديد --> {% img "/images/hero.jpg", "Yousef — hero image", "(max-width: 900px) 100vw, 900px" %}
<picture>
بـ AVIF/WebP + JPEG وsrcset
بأحجام مختلفة.في ملف الستايـل الأساسي (مثلاً /_includes/assets/css/main.css
أو أينما كان):
cssimg, picture { max-width: 100%; height: auto; display: block; }
/
(زي /images/x.jpg
) — ده ممتاز لأن موقعك User Site على الجذر (مش Project Page).bashnpx @11ty/eleventy --serve # افتح http://localhost:8080 وشوف الصور والناف git add . git commit -m "Use @11ty/eleventy-img for responsive, optimized images + hide extra nav items" git push origin main
<img>
عادية في أماكن ما بدّلتهاش:
ده يقلل CLS ويثبت اللياوت.html<img src="/images/pic.jpg" alt="..." width="1200" height="800" loading="lazy" decoding="async">
ابعتلي:
/_includes/layouts/base.njk
archive.njk
و photos.njk
الـ front matter بتاعهمindex.njk
)وأنا هبعتلك باتش جاهز (diff) تغيّره سطر بسطر. 🙌
الخطوة 3.3) استبدل <img> العادية بالـ shortcode
افتح الصفحات اللي فيها صور كتير (خصوصًا index.njk وملفات المشاريع) واستبدل:
html
<!-- القديم --> <img src="/images/hero.jpg" alt="Yousef hero"> <!-- الجديد -->{% img "/images/hero.jpg", "Yousef — hero image", "(max-width: 900px) 100vw, 900px" %}
textالـ shortcode هيولّد <picture> بـ AVIF/WebP + JPEG وsrcset بأحجام مختلفة. كل الصور هتبقى lazy-loaded تلقائيًا. لو عندك صور ضخمة جدًا (مثلاً 4000px)، الـ shortcode هيطلع نسخ أصغر تناسب الموبايل والديستوب.
الخطوة 3.4) تأكد إن الصور بتتمدد صح في CSS
في ملف الستايـل الأساسي (مثلاً /_includes/assets/css/main.css أو أينما كان):
css
img, picture {
max-width: 100%;
height: auto;
display: block;
}
الخطوة 3.5) مسارات الصور (علاج سقوط التحميل)
textاستخدم مسارات جذرية تبدأ بـ / (زي /images/x.jpg) — ده ممتاز لأن موقعك User Site على الجذر (مش Project Page). لو في صور ريموت (لينكات خارجية)، البلجن يقدر يحملها ويبني منها نسخ محليًا (يفضل تنظّف اللينكات الخارجيّة وتخليها محليّة إن أمكن)
4) تحسينات إضافية سريعة (اختياري بس قوية)
<img src="/images/pic.jpg" alt="..." width="1200" height="800" loading="lazy" decoding="async">textأضف أبعاد للصورة لو هتسيب <img> عادية في أماكن ما بدّلتهاش: html
ده يقلل CLS ويثبت اللياوت.
ضغط SVG يدويًا لو عندك أيقونات SVG (SVGO).
لو عندك جاليري تقيل، استخدم pagination على الصور/المشاريع بدل ما تحط كله في صفحة واحدة.
لو صور كتير جدًا في الهوم، فكّر تقلل العدد أو اعمل LQIP/placeholder (البلجن يقدر يتعمله إعداد متقدم لاحقًا).
مش عارف اعمل اخطوات دي ياريت واحده واحده وتجيب اكواد من الجزور علي تريمنال
وعاوز زي ما بيظهر علي الديسك توب يظهر علي جميع الاجهزه خد وقتك وهات افضل اجابه
جامد يا يوسف! هنمشيها خطوة–خطوة بأوامر ترمينال بس، من غير لَفّ ودوران. خلّي الترمينال مفتوح في جذر المشروع بتاعك (اللي فيه package.json
).
كل خطوة عاملة باك أب قبل أي تعديل عشان لو حبيت ترجع.
bashgit checkout -b fix/mobile-and-images
bash# باك أب وبعدين احذف السطر cp index.njk index.njk.bak sed -i '' '/DEBUG from index\.njk/d' index.njk git add index.njk git commit -m "Remove debug line from index.njk"
bashmkdir -p assets/css tee assets/css/overrides.css > /dev/null <<'CSS' /* اخفاء عناصر معينة من الناف */ .site-nav a[href="/posts/"], .site-nav a[href="/photos/"] { display: none !important; } /* صور مرنة على كل الأجهزة */ img, picture { max-width: 100%; height: auto; display: block; } CSS
فعّل نسخ مجلد assets/
في البيلد، ولو لسه ما فعلنهوش (هنعملها في خطوة #3):
ضيف اللينك بتاع ملف الـ CSS في القالب الأساسي قبل </head>
:
bash# باك أب cp _includes/layouts/base.njk _includes/layouts/base.njk.bak # أضف لينك الـ overrides.css قبل وسم </head> (لو الملف موجود في نفس المسار) sed -i '' 's#</head># <link rel="stylesheet" href="/assets/css/overrides.css">\n</head>#' _includes/layouts/base.njk git add _includes/layouts/base.njk assets/css/overrides.css git commit -m "Add CSS override (hide Archive/Photos, responsive images)"
لو عايز تخبّي الصفحات من المصدر بدل CSS:
bash# Archive cp archive.njk archive.njk.bak python3 - <<'PY' import re,sys p="archive.njk" t=open(p).read() if "eleventyNavigation:" in t and "hidden:" not in t: t=re.sub(r'(eleventyNavigation:\s*\n)', r'\1 hidden: true\n', t, count=1, flags=re.M) open(p,"w").write(t) PY # Photos cp photos.njk photos.njk.bak python3 - <<'PY' import re,sys p="photos.njk" t=open(p).read() if "eleventyNavigation:" in t and "hidden:" not in t: t=re.sub(r'(eleventyNavigation:\s*\n)', r'\1 hidden: true\n', t, count=1, flags=re.M) open(p,"w").write(t) PY git add archive.njk photos.njk git commit -m "Hide Archive & Photos in eleventyNavigation"
bashnpm i -D @11ty/eleventy-img
.eleventy.js
(هنكتب نسخة كاملة مع باك أب)لو الملف عندك فيه إعدادات كتير، قولّي قبل ما تستبدله. التحت ده فيه كل اللي نحتاجه: البلجن + الشورتكود + نسخ
assets/
وimages/
.
bashcp .eleventy.js .eleventy.js.bak tee .eleventy.js > /dev/null <<'JS' const eleventyNavigation = require("@11ty/eleventy-navigation"); const Image = require("@11ty/eleventy-img"); const path = require("path"); async function imageShortcode(src, alt = "", sizes = "(max-width: 900px) 100vw, 900px") { if (!alt) alt = path.basename(src).replace(/\.(avif|webp|jpe?g|png|gif|svg)$/i, "").replace(/[-_]+/g, " "); let metadata = await Image(src, { widths: [320, 640, 900, 1200, 1600], formats: ["avif", "webp", "jpeg"], outputDir: "_site/img/", urlPath: "/img/", sharpJpeg: { quality: 78, mozjpeg: true }, sharpWebp: { quality: 74 }, sharpAvif: { quality: 60 }, cacheOptions: { duration: "1y" } }); const imageAttributes = { alt, sizes, loading: "lazy", decoding: "async" }; return Image.generateHTML(metadata, imageAttributes, { whitespaceMode: "inline" }); } module.exports = function(eleventyConfig) { eleventyConfig.addPlugin(eleventyNavigation); // Shortcodes لكل المحركات eleventyConfig.addNunjucksAsyncShortcode("img", imageShortcode); eleventyConfig.addLiquidShortcode("img", (src, alt, sizes) => imageShortcode(src, alt, sizes)); eleventyConfig.addJavaScriptFunction("img", imageShortcode); // نسخ أصول ثابتة إلى _site eleventyConfig.addPassthroughCopy("assets"); // لو عندك مجلد صور خام try { eleventyConfig.addPassthroughCopy("images"); } catch {} return { dir: { input: ".", output: "_site" } }; }; JS git add .eleventy.js git commit -m "Configure @11ty/eleventy-img shortcode and passthrough assets"
<img>
القديمة بالـ shortcode تلقائيًاهحوّل الشائع تلقائيًا (src + alt). لو عندك حالات معقدة جدًا، هنبص عليها يدويًا.
bashmkdir -p scripts tee scripts/convert-imgs.js > /dev/null <<'JS' const fs = require('fs'); function convert(content) { // ابحث عن <img ...> return content.replace(/<img\s+([^>]*?)>/gi, (m, attrs) => { const src = (attrs.match(/src\s*=\s*"(.*?)"/i) || [])[1] || (attrs.match(/src\s*=\s*'(.*?)'/i) || [])[1]; const alt = (attrs.match(/alt\s*=\s*"(.*?)"/i) || [])[1] || (attrs.match(/alt\s*=\s*'(.*?)'/i) || [])[1] || ""; if (!src) return m; // سيبه لو من غير src const sizes = '(max-width: 900px) 100vw, 900px'; // نونجكس shortcode return `{% img "${src}", "${alt.replace(/"/g,'\\"')}", "${sizes}" %}`; }); } const files = process.argv.slice(2); let changed = 0; for (const f of files) { if (!fs.existsSync(f) || !fs.lstatSync(f).isFile()) continue; const old = fs.readFileSync(f, 'utf8'); const nu = convert(old); if (nu !== old) { fs.copyFileSync(f, f + '.bak'); fs.writeFileSync(f, nu); changed++; console.log('Converted:', f); } } console.log('Done. Files changed:', changed); JS # مرّر الملفات الشائعة: الصفحة الرئيسية + صفحات .njk و .md node scripts/convert-imgs.js index.njk $(find projects -type f $ -name '*.njk' -o -name '*.md' $ 2>/dev/null) $(find posts -type f $ -name '*.njk' -o -name '*.md' $ 2>/dev/null) $(find . -maxdepth 1 -type f -name '*.njk') git add -A git commit -m "Replace <img> with Eleventy responsive {% img %} shortcode"
لو عندك صور بمسارات خارجية (روابط http/https)، البلجن هيحمّلها وقت البيلد ويولّد نسخ سريعة. الأفضل برضه على المدى الطويل تنقل الصور لمجلد محلي (زي
images/
) وتستخدم مسارات جذرية تبدأ بـ/images/...
.
لو مش موجودة، ضيف وسم viewport في <head>
:
bash# سيضيف الوسم قبل </head> لو مش موجود grep -q 'name="viewport"' _includes/layouts/base.njk || \ sed -i '' 's#</head># <meta name="viewport" content="width=device-width, initial-scale=1">\n</head>#' _includes/layouts/base.njk git add _includes/layouts/base.njk git commit -m "Add responsive viewport meta"
bash# تجربة محلية npx @11ty/eleventy --serve # افتح http://localhost:8080 وشوف: # - مفيش DEBUG # - Archive/Photos اختفوا من الناف # - الصور بتطلع <picture> وبتتحمل أسرع # لما تبقى تمام: git push origin fix/mobile-and-images # أو دمّج للـ main مباشرة: git checkout main git merge --no-ff fix/mobile-and-images -m "Merge: mobile nav cleanup + responsive images" git push origin main
بما إنك بالفعل مفعّل نشر GitHub Pages عن طريق GitHub Actions، البيلد هيشتغل أوتوماتيك وينشر النسخة المحدثة.
max-width:100%
).srcset
وأحجام مناسبة للموبايل والديستوب.hidden: true
داخل الصفحات نفسها).assets/
(وأي images/
لو موجود) للناتج، فالمسارات تبقى ثابتة.لو واجهت أي ملف ما اتبدّلتش فيه الصور تلقائيًا، ابعتهولي أو قلّي اسمه وأنا أكتبلك سطر تحويل مخصوص له. وبرضه لو عندك جزء الـ nav في base.njk
وعايز تعمله “قائمة مسموح بها” (allowlist) بدل CSS، ابعتهولي وأظبطلك اللوب بـ {% if item.key in allowed %}
.
(base) Yousef@Apples-MacBook-Pro my-portfolio % # سيضيف الوسم قبل </head> لو مش موجود
grep -q 'name="viewport"' _includes/layouts/base.njk ||
sed -i '' 's#</head># <meta name="viewport" content="width=device-width, initial-scale=1">\n</head>#' _includes/layouts/base.njk
git add _includes/layouts/base.njk
git commit -m "Add responsive viewport meta"
zsh: no such file or directory: /head
On branch fix/mobile-and-images
nothing to commit, working tree clean
(base) Yousef@Apples-MacBook-Pro my-portfolio % npx @11ty/eleventy --serve
[11ty] Problem writing Eleventy templates: (more in DEBUG output)
[11ty] 1. Having trouble rendering njk template ./archive.njk (via TemplateContentRenderError)
[11ty] 2. (./archive.njk)
[11ty] Template render error: (/Users/Yousef/my-portfolio/_includes/postslist.njk)
[11ty] Error: filter not found: htmlDateString (via Template render error)
[11ty]
[11ty] Original error stack trace: Template render error: (./archive.njk)
[11ty] Template render error: (/Users/Yousef/my-portfolio/_includes/postslist.njk)
[11ty] Error: filter not found: htmlDateString
[11ty] at Object._prettifyError (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/lib.js:32:11)
[11ty] at /Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:464:19
[11ty] at eval (eval at _compile (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:527:18), <anonymous>:30:11)
[11ty] at /Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:471:11
[11ty] at Template.root [as rootRenderFunc] (eval at _compile (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:527:18), <anonymous>:105:3)
[11ty] at Template.render (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:454:10)
[11ty] at eval (eval at _compile (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:527:18), <anonymous>:29:10)
[11ty] at fn (/Users/Yousef/my-portfolio/node_modules/a-sync-waterfall/index.js:26:24)
[11ty] at /Users/Yousef/my-portfolio/node_modules/a-sync-waterfall/index.js:66:22
[11ty] at executeSync (/Users/Yousef/my-portfolio/node_modules/a-sync-waterfall/index.js:8:15)
[11ty] Wrote 0 files in 0.39 seconds (v2.0.1)
(base) Yousef@Apples-MacBook-Pro my-portfolio % rm -rf _site
npx @11ty/eleventy --serve --port 8087
[11ty] Problem writing Eleventy templates: (more in DEBUG output)
[11ty] 1. Having trouble rendering njk template ./archive.njk (via TemplateContentRenderError)
[11ty] 2. (./archive.njk)
[11ty] Template render error: (/Users/Yousef/my-portfolio/_includes/postslist.njk)
[11ty] Error: filter not found: htmlDateString (via Template render error)
[11ty]
[11ty] Original error stack trace: Template render error: (./archive.njk)
[11ty] Template render error: (/Users/Yousef/my-portfolio/_includes/postslist.njk)
[11ty] Error: filter not found: htmlDateString
[11ty] at Object._prettifyError (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/lib.js:32:11)
[11ty] at /Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:464:19
[11ty] at eval (eval at _compile (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:527:18), <anonymous>:30:11)
[11ty] at /Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:471:11
[11ty] at Template.root [as rootRenderFunc] (eval at _compile (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:527:18), <anonymous>:105:3)
[11ty] at Template.render (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:454:10)
[11ty] at eval (eval at _compile (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:527:18), <anonymous>:29:10)
[11ty] at fn (/Users/Yousef/my-portfolio/node_modules/a-sync-waterfall/index.js:26:24)
[11ty] at /Users/Yousef/my-portfolio/node_modules/a-sync-waterfall/index.js:66:22
[11ty] at executeSync (/Users/Yousef/my-portfolio/node_modules/a-sync-waterfall/index.js:8:15)
[11ty] Copied 1 file / Wrote 0 files in 0.34 seconds (v2.0.1)
تمام يا يوسف، حصل عندك حاجتين واضحين:
sed
بتاع إضافة <meta viewport>
خبط مع zsh وعمل no such file or directory: /head
.htmlDateString
جواه postslist.njk
واللي بتستدعيه صفحة archive.njk
.هنصلّح الاتنين خطوة–خطوة من الترمينال بس. ✨
<meta name="viewport">
بطريقة مضمونة (من غير sed)استبدل أمر sed
بـ Python صغير يضيف الوسم قبل </head>
لو مش موجود:
bash# 1) باك أب cp _includes/layouts/base.njk _includes/layouts/base.njk.bak # 2) أضف وسم viewport بأمان python3 - <<'PY' import re, sys, io p = "_includes/layouts/base.njk" t = io.open(p, encoding="utf-8").read() if 'name="viewport"' not in t: t = re.sub(r'</head>', ' <meta name="viewport" content="width=device-width, initial-scale=1">\n</head>', t, count=1, flags=re.I) io.open(p, "w", encoding="utf-8").write(t) print("✅ Added viewport meta") else: print("ℹ️ Viewport already exists") PY git add _includes/layouts/base.njk git commit -m "Add responsive viewport meta (safe python edit)" || echo "No changes to commit"
ملاحظة: سبب خطأ zsh غالبًا إن السطر اتكسر قبل ما الـ
||
يكتمل، فالـ shell فهم جزء</head>
كأنه redirection. الطريقة بالـ Python تفاديًا لأي parsing.
الفلتر ده مش built-in؛ لازم نضيفه بإيدينا (زي قوالب Eleventy الرسمية). هنستعمل luxon
للتنسيق:
bash# 1) نزّل luxon (ولو eleventy-img مش متثبت، مفيش مشكلة نعيد تثبيته) npm i -D luxon @11ty/eleventy-img
دلوقتي هنكتب .eleventy.js
كامل فيه:
htmlDateString
و readableDate
assets/
و images/
لو موجودةلو عندك تعديلات خاصة جوّه
.eleventy.js
قولّي قبل ما تغيّر. لو ماعندكش، كمّل بالأوامر دي:
bash# 2) باك أب وبعدين اكتب ملف .eleventy.js جديد جاهز cp .eleventy.js .eleventy.js.bak 2>/dev/null || true tee .eleventy.js > /dev/null <<'JS' const eleventyNavigation = require("@11ty/eleventy-navigation"); const Image = require("@11ty/eleventy-img"); const { DateTime } = require("luxon"); const path = require("path"); // === Responsive Image Shortcode === async function imageShortcode(src, alt = "", sizes = "(max-width: 900px) 100vw, 900px") { if (!alt) alt = path.basename(src).replace(/\.(avif|webp|jpe?g|png|gif|svg)$/i, "").replace(/[-_]+/g, " "); let metadata = await Image(src, { widths: [320, 640, 900, 1200, 1600], formats: ["avif", "webp", "jpeg"], outputDir: "_site/img/", urlPath: "/img/", sharpJpeg: { quality: 78, mozjpeg: true }, sharpWebp: { quality: 74 }, sharpAvif: { quality: 60 }, cacheOptions: { duration: "1y" } }); const imageAttributes = { alt, sizes, loading: "lazy", decoding: "async" }; return Image.generateHTML(metadata, imageAttributes, { whitespaceMode: "inline" }); } module.exports = function(eleventyConfig) { // Plugins eleventyConfig.addPlugin(eleventyNavigation); // Filters (لأرشيف وغيره) eleventyConfig.addFilter("htmlDateString", (dateObj) => DateTime.fromJSDate(dateObj, { zone: "utc" }).toISODate() ); eleventyConfig.addFilter("readableDate", (dateObj, format = "dd LLL yyyy") => DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat(format) ); // Shortcodes eleventyConfig.addNunjucksAsyncShortcode("img", imageShortcode); eleventyConfig.addLiquidShortcode("img", (src, alt, sizes) => imageShortcode(src, alt, sizes)); eleventyConfig.addJavaScriptFunction("img", imageShortcode); // Static passthrough eleventyConfig.addPassthroughCopy("assets"); try { eleventyConfig.addPassthroughCopy("images"); } catch {} return { dir: { input: ".", output: "_site" } }; }; JS git add .eleventy.js git commit -m "Add date filters + responsive images shortcode + passthrough"
دلوقتي جرّب البيلد المحلي:
bashrm -rf _site .cache npx @11ty/eleventy --serve --port 8087
المفروض الخطأ بتاع htmlDateString
يختفي، والصفحات تطلع تمام.
لحد ما ترتّبها، تقدر توقف توليدها مؤقتًا:
bashcp archive.njk archive.njk.bak # ضيف permalink: false في الـ front matter awk 'BEGIN{p=1} /^---/{c++} {print} c==1 && $0 ~ /^---$/ && p {print "permalink: false"; p=0}' archive.njk > /tmp/_a && mv /tmp/_a archive.njk git add archive.njk git commit -m "Temporarily disable building Archive page (permalink: false)"
كده حتى لو فيه فلاتر ناقصة جوّا الملف، Eleventy مش هيبني الصفحة أصلاً. (اختياري لو محتاج تركيزك كله على الهوم/باقي الصفحات الأول.)
لو كنت ضايف قبل كده ملف assets/css/overrides.css
وفيه:
css/* إخفاء روابط معينة من الناف */ .site-nav a[href="/posts/"], .site-nav a[href="/photos/"] { display: none !important; } /* صور مرنة */ img, picture { max-width: 100%; height: auto; display: block; }
تأكد إنه متضمَّن في <head>
:
bashgrep -n 'overrides.css' _includes/layouts/base.njk || \ sed -i '' 's#</head># <link rel="stylesheet" href="/assets/css/overrides.css">\n</head>#' _includes/layouts/base.njk git add _includes/layouts/base.njk git commit -m "Ensure overrides.css is included" || true
لو أمر
sed
زعل تاني، قفله بنفس أسلوب الـ Python، وقولي أكتبهولك بنفس الطريقة.
لو البيلد المحلي اشتغل كويس على http://localhost:8087
:
bashgit push origin fix/mobile-and-images # لو حابب تدمج على main فورًا: git checkout main git merge --no-ff fix/mobile-and-images -m "Mobile viewport + date filters + responsive images" git push origin main
بما إنك مفعّل GitHub Actions لنشر Pages، هيبني وينشر تلقائي.
<meta viewport>
+ CSS يجعل الصور مرنة، فالموبايل يشوف Layout مضبوط.<img>
بقت Shortcode بيولّد <picture>
بـ AVIF/WebP+JPEG وsrcset
لأحجام مختلفة + loading="lazy"
→ تحميل أسرع وما يقعّش.htmlDateString
و readableDate
) فالأرشيف يرن بدون Errors.permalink: false
) لحد ما ترتّبها.لو تحب، ابعتلي سطور الـ nav في /_includes/layouts/base.njk
وأنا أعملهالك Allow-list (يعني ما يطلعش غير Home / About / Projects / Contact / CV فقط) بدل الاعتماد على CSS. وبرضه لو ظهر لك Error جديد، انسخهالي زي ما عملت كده وأنا أديك أوامر ترمينال جاهزة للـ fix. 💪
(base) Yousef@Apples-MacBook-Pro my-portfolio % git push origin main
Counting objects: 1, done.
Writing objects: 100% (1/1), 243 bytes | 243.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To https://github.com/YousefMohamd/YousefMohamd.github.io.git
6780df5..81ad850 main -> main
(base) Yousef@Apples-MacBook-Pro my-portfolio % # 1) باك أب
cp _includes/layouts/base.njk _includes/layouts/base.njk.bak
python3 - <<'PY'
import re, sys, io
p = "_includes/layouts/base.njk"
t = io.open(p, encoding="utf-8").read()
if 'name="viewport"' not in t:
t = re.sub(r'</head>', ' <meta name="viewport" content="width=device-width, initial-scale=1">\n</head>', t, count=1, flags=re.I)
io.open(p, "w", encoding="utf-8").write(t)
print("✅ Added viewport meta")
else:
print("ℹ️ Viewport already exists")
PY
git add _includes/layouts/base.njk
git commit -m "Add responsive viewport meta (safe python edit)" || echo "No changes to commit"
zsh: parse error near )' (base) Yousef@Apples-MacBook-Pro my-portfolio % # 1) نزّل luxon (ولو eleventy-img مش متثبت، مفيش مشكلة نعيد تثبيته) npm i -D luxon @11ty/eleventy-img zsh: parse error near
)'
(base) Yousef@Apples-MacBook-Pro my-portfolio % >....
// Filters (لأرشيف وغيره)
eleventyConfig.addFilter("htmlDateString", (dateObj) =>
DateTime.fromJSDate(dateObj, { zone: "utc" }).toISODate()
);
eleventyConfig.addFilter("readableDate", (dateObj, format = "dd LLL yyyy") =>
DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat(format)
);
// Shortcodes
eleventyConfig.addNunjucksAsyncShortcode("img", imageShortcode);
eleventyConfig.addLiquidShortcode("img", (src, alt, sizes) => imageShortcode(src, alt, sizes));
eleventyConfig.addJavaScriptFunction("img", imageShortcode);
// Static passthrough
eleventyConfig.addPassthroughCopy("assets");
try { eleventyConfig.addPassthroughCopy("images"); } catch {}
return {
dir: { input: ".", output: "_site" }
};
};
JS
git add .eleventy.js
git commit -m "Add date filters + responsive images shortcode + passthrough"
zsh: parse error near `)'
(base) Yousef@Apples-MacBook-Pro my-portfolio % rm -rf _site .cache
npx @11ty/eleventy --serve --port 8087
[11ty] Problem writing Eleventy templates: (more in DEBUG output)
[11ty] 1. Having trouble rendering njk template ./archive.njk (via TemplateContentRenderError)
[11ty] 2. (./archive.njk)
[11ty] Template render error: (/Users/Yousef/my-portfolio/_includes/postslist.njk)
[11ty] Error: filter not found: htmlDateString (via Template render error)
[11ty]
[11ty] Original error stack trace: Template render error: (./archive.njk)
[11ty] Template render error: (/Users/Yousef/my-portfolio/_includes/postslist.njk)
[11ty] Error: filter not found: htmlDateString
[11ty] at Object._prettifyError (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/lib.js:32:11)
[11ty] at /Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:464:19
[11ty] at eval (eval at _compile (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:527:18), <anonymous>:30:11)
[11ty] at /Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:471:11
[11ty] at Template.root [as rootRenderFunc] (eval at _compile (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:527:18), <anonymous>:105:3)
[11ty] at Template.render (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:454:10)
[11ty] at eval (eval at _compile (/Users/Yousef/my-portfolio/node_modules/nunjucks/src/environment.js:527:18), <anonymous>:29:10)
[11ty] at fn (/Users/Yousef/my-portfolio/node_modules/a-sync-waterfall/index.js:26:24)
[11ty] at /Users/Yousef/my-portfolio/node_modules/a-sync-waterfall/index.js:66:22
[11ty] at executeSync (/Users/Yousef/my-portfolio/node_modules/a-sync-waterfall/index.js:8:15)
[11ty] Copied 1 file / Wrote 0 files in 0.39 seconds (v2.0.1)
(base) Yousef@Apples-MacBook-Pro my-portfolio %
حاضر يا يوسف! واضح إن الـ zsh دخل في “وضع الاستكمال” عندك (بتشوف بداية السطر >
وساعات يطلع parse error near ')'
) ده بيحصل لما يكون فيه سطر اتنسخ ناقص أقواس/كوتس أو هيرودوك.
الحل السريع: قبل أي أوامر جديدة اضغط Ctrl+C
مرة أو اتنين لحد ما ترجع للبرومبت العادي اللي فيه %
.
هنشتغل دلوقتي بخطوات “مضمونة” من غير sed
ولا heredoc — هنستخدم nano
عشان ما يحصلش تاني لَخبَطة كوتس.
>
اضغط Ctrl+C الأول)npm i -D luxon @11ty/eleventy-img
لو الأمر ده اشتغل من غير Errors، كمل. لو ظهر أي سطر يبدأ بـ >
اضغط Ctrl+C
وبعدين كرّر الأمر تاني.
.eleventy.js
هنكتب نسخة كاملة فيها:
@11ty/eleventy-navigation
@11ty/eleventy-img
htmlDateString
و readableDate
assets
و images
لو موجودينافتح الملف بالمحرر:
nano .eleventy.js
امسح كل محتوى الملف وحط ده مكانه (انسخ زي ما هو):
jsconst eleventyNavigation = require("@11ty/eleventy-navigation"); const Image = require("@11ty/eleventy-img"); const { DateTime } = require("luxon"); const path = require("path"); // Responsive Image Shortcode async function imageShortcode(src, alt = "", sizes = "(max-width: 900px) 100vw, 900px") { if (!alt) { alt = path.basename(src).replace(/\.(avif|webp|jpe?g|png|gif|svg)$/i, "").replace(/[-_]+/g, " "); } let metadata = await Image(src, { widths: [320, 640, 900, 1200, 1600], formats: ["avif", "webp", "jpeg"], outputDir: "_site/img/", urlPath: "/img/", sharpJpeg: { quality: 78, mozjpeg: true }, sharpWebp: { quality: 74 }, sharpAvif: { quality: 60 }, cacheOptions: { duration: "1y" } }); const imageAttributes = { alt, sizes, loading: "lazy", decoding: "async" }; return Image.generateHTML(metadata, imageAttributes, { whitespaceMode: "inline" }); } module.exports = function(eleventyConfig) { // Plugins eleventyConfig.addPlugin(eleventyNavigation); // Date filters used in archive/posts lists eleventyConfig.addFilter("htmlDateString", (dateObj) => DateTime.fromJSDate(dateObj, { zone: "utc" }).toISODate() ); eleventyConfig.addFilter("readableDate", (dateObj, format = "dd LLL yyyy") => DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat(format) ); // Shortcodes eleventyConfig.addNunjucksAsyncShortcode("img", imageShortcode); eleventyConfig.addLiquidShortcode("img", (src, alt, sizes) => imageShortcode(src, alt, sizes)); eleventyConfig.addJavaScriptFunction("img", imageShortcode); // Static passthrough eleventyConfig.addPassthroughCopy("assets"); try { eleventyConfig.addPassthroughCopy("images"); } catch {} return { dir: { input: ".", output: "_site" } }; };
احفظ: Ctrl+O
ثم Enter
اخرج: Ctrl+X
وبعدين:
textgit add .eleventy.js git commit -m "Eleventy: add date filters + responsive images shortcode"
افتح القالب الأساسي:
nano _includes/layouts/base.njk
دَوَّر بعينك على </head>
وحط السطر ده فوقها مباشرةً (لو مش موجود فعلًا):
html<meta name="viewport" content="width=device-width, initial-scale=1">
(لو لقيت السطر موجود خلاص سيبه.)
احفظ واخرج، ثم:
textgit add _includes/layouts/base.njk git commit -m "Add mobile viewport meta"
لو لسه مش عامل الملف، اعمله وأضف سطرين مهمين:
textmkdir -p assets/css nano assets/css/overrides.css
ضع داخله:
css/* اخفاء روابط معينة من الناف */ .site-nav a[href="/posts/"], .site-nav a[href="/photos/"] { display: none !important; } /* صور مرنة */ img, picture { max-width: 100%; height: auto; display: block; }
احفظ واخرج. بعدين لازم نتأكد إن الملف ده متضمَّن داخل <head>
.
افتح القالب الأساسي تاني:
nano _includes/layouts/base.njk
لو مافيش سطر بيوصل للملف ده، زَوِّد السطر ده قبل </head>
:
html<link rel="stylesheet" href="/assets/css/overrides.css">
احفظ واخرج، ثم:
textgit add assets/css/overrides.css _includes/layouts/base.njk git commit -m "Add CSS overrides (hide archive/photos + responsive imgs)"
لاحقًا نقدر نعملها “من المصدر” بإضافة
hidden: true
في front matter لصفحات Archive/Photos — بس دلوقتي الـ CSS حل سريع شغّال على الموبايل والديستوب.
نظّف وبعدين سيرف:
textrm -rf _site .cache npx @11ty/eleventy npx @11ty/eleventy --serve --port 8087
المفروض:
htmlDateString
.<picture>
مع WebP/AVIF + JPEG و loading="lazy"
.لو كله تمام:
git push origin main
الـ GitHub Actions هتبني وتنشر.
>
أو quote>
، اضغط Ctrl+C
قبل أي لصق جديد.<<'JS'
أو <<'PY'
لو مش متعوّد عليها؛ استخدم nano
زي فوق.لو بعد الخطوات دي لسه عندك صفحة Archive مش محتاجها دلوقتي، ممكن توقف بنائها مؤقتًا:
nano archive.njk
أضف في الـ front matter (الجزء بين ---
في أعلى الملف):
permalink: false
احفظ واخرج:
textgit add archive.njk git commit -m "Temporarily disable Archive page" git push origin main
أنا جاهز لو طلع لك أي Error جديد—انسخهالي حرفيًا وأنا أديك الأوامر المناسبة فورًا. 💪