اهلا ومرحبا بكم في مدونه : Cyber1101 انظم للمجتمع

تطبيق الويب التقدمي (Progressive web application) ويسمى اختصارًا بـ (PWA) هو أحد أنواع التطبيقات التي تعمل عبر الويب مع قابليتها للتثبيت علي الأجهزة الجوالة، وتكون هذه التطبيقات مبنية باستخدام تقنيات الويب بما في ذلك جافاسكربت وHTML وكذلك CSS، بهدف صنع تطبيق يعمل على مختلف الأنظمة التي تتضمن متصفحات تُطابق المعايير، بما في ذلك أجهزة سطح المكتب وكذلك الهواتف الذكية.

كيف إنشاء تطبيق الويب المتقدم PWA لمدونات بلوجر

تطبيق الويب التقدمي (PWA)

إذن تطبيق الويب PWA ليس تقنية أو إطار عمل جافاسكريبت جديد، وإنما مجموعة من الممارسات الجيدة والمزايا التي يجب أن تتوفر في تطبيق الويب ليكون شبيها بتطبيقات الهواتف الذي اعتدنا تحميلها من متجر Play Store بالنسبة لهواتف أندرويد و App Store بالنسبة لهواتف وأجهزة شركة Apple. الهدف هو منح مستخدمي تطبيقات الويب تجربة استخدام تماثل تلك الموجودة في Native Applications. يفترض في هذا النوع من التطبيقات أن تعمل بشكل جيد في كافة الأجهزة على اختلاف مقوماتها وإمكاناتها التقنية. قد لا يكون بالإمكان مثلا إتاحة بعض المزايا والوظائف في بعض الهواتف أو الأجهزة القديمة، ولكن يجب ضمان أن يظل التطبيق يعمل فيها بشكل جيد وبالخصوص من ناحية الأداء والسرعة ونظراً للمزايا هذا أن كونت تملك مدونة بلوجر أو موقع ويب يجب عليك تثبيت تطبيق PWA علي موقعك الإلكتروني

خطوات إنشاء PWA لـ Blogger

من أجل إنشاء تطبيق ويب تقدمي ، ستحتاج إلى إضافة بعض الميزات إلى موقع الويب الخاص بك. مما يسمح لموقعك بالعمل دون اتصال بالإنترنت ، ودفع الإشعارات عند عودة المستخدمين إلى موقعك. يمكنك أيضًا تثبيت رسالة Add-to-Home على موقع الويب الخاص بك والتي تطالب المستخدمين بإضافة موقعك أو تطبيقك إلى الشاشة الرئيسية على أجهزتهم المحمولة أو أجهزة الكمبيوتر.

متطلبات

قبل أن نبدأ ، هناك العديد من الأشياء التي يجب أن تكون مطلوبة لتفعيل PWA :-

  1. يجب تجهيز شعار مدونتك بحجم 512 × 512 .png
  2. يجب أن يكون لديك حساب على GitHub
  3. يجب أن تمر المدونة عبر إدارة DNS: Cloudflare

تحميل الأيقونات

  1. قم بإعداد رمز لمدونتك بحجم .png 512 × 512.
  2. إعادة تسمية الملف باسم android-icon-512x512.png
  3. انتقل إلى favicon-generator.org وقم بتحميل رمز المدونة.
  4. قم بتنزيل الأيقونة المفضلة التي تم إنشاؤها واستخراج الملفات.
  5. احذف الملفات غير الضرورية مثل:
  • browserconfig.xml
  • manifest.json
شاهد أيضاً :-

رفع الأيقونات علي GitHub

  1. قم بإنشاء مستودع على GitHub.com، على سبيل المثال icon-medoapp
  2. وقم بتحميل جميع ملفات الرموز في main الفرع.
  3. قم بتحميل الشعار مدونتك الأصلي أيضًا معهم ، أي android-icon-512x512.png.
  4. سيكون العدد الإجمالي للرموز حوالي 26.

انشاء خوادم Cloudflare

  • 1- قم بتسجيل الدخول إلى حساب في Cloudflare.com.
  • 2- انتقل إلى قسم العمال وانقر على إدارة العمال.
  • 3- انقر فوق إنشاء خدمة وأعد تسمية الخدمة باسم main-blogname، على سبيل المثال main-medoapp. بعد احذف النصي البرامجي الحالي ، واستبدله بالنص التالي:
addEventListener("fetch", event => {
  event.respondWith(handleRequest(event))
})

//const BUCKET_NAME = "main"
const BUCKET_URL = `https://cdn.statically.io/gh/Mr-medo-net/app-icon`

async function serveAsset(event) {
  const url = new URL(event.request.url)
  const cache = caches.default
  let response = await cache.match(event.request)

  if (!response) {
    response = await fetch(`${BUCKET_URL}${url.pathname}`)
    const headers = { "cache-control": "public, max-age=14400" }
    response = new Response(response.body, { ...response, headers })
    event.waitUntil(cache.put(event.request, response.clone()))
  }
  return response
}

async function handleRequest(event) {
  if (event.request.method === "GET") {
    let response = await serveAsset(event)
    if (response.status > 399) {
      response = new Response(response.statusText, { status: response.status })
    }
    return response
  } else {
    return new Response("Method not allowed", { status: 405 })
  }
}
استبدل الأجزاء المميزة بالون الاحمر باسم مستخدم GitHub الخاص بك انقر فوق حفظ ونشر.

Manifest.json

بالطريقة نفسها ، أنشئ خدمة وأعد تسميتها manifest-blogname، على سبيل المثال manifest-medoapp. استبدل الكود الموجود بالكود التالي:
addEventListener("fetch", event => {
  const data = {
    name: "Master Medo Website",
    short_name: "Master Medo app",
    description: "قم بتحميل تطبيق موقعنا الالكتروني الان وتصفح احدث المشاركات بدون انترنت. - Install APP Now Mr-Medo.Net",
    display: "standalone",
    prefer_related_applications: false,
    start_url: "\/?utm_source=homescreen",
    scope: "\/",
    background_color: "#BA0000",
    theme_color: "#BA0000",
    icons: [
      {
      src: "\/main\/android-icon-512x512.png",
      sizes: "512x512",
      type: "image\/png",
      density: "4.0",
      purpose: "any maskable"
      },
      {
      src: "\/main\/android-icon-192x192.png",
      sizes: "192x192",
      type: "image\/png",
      density: "4.0",
      purpose: "any maskable"
      },
      {
      src: "\/main\/apple-icon-144x144.png",
      sizes: "144x144",
      type: "image\/png",
      density: "3.0",
      purpose: "any maskable"
      },
      {
      src: "\/main\/android-icon-96x96.png",
      sizes: "96x96",
      type: "image\/png",
      density: "2.0",
      purpose: "any maskable"
      },
      {
      src: "\/main\/android-icon-72x72.png",
      sizes: "72x72",
      type: "image\/png",
      density: "1.5",
      purpose: "any maskable"
      },
      {
      src: "\/main\/android-icon-48x48.png",
      sizes: "48x48",
      type: "image\/png",
      density: "1.0",
      purpose: "any maskable"
      },
      {
      src: "\/main\/android-icon-36x36.png",
      sizes: "36x36",
      type: "image\/png",
      density: "0.75",
      purpose: "any maskable"
      }
    ],
    shortcuts: [
      {
      name: "الصفحة الرئيسية",
      short_name: "Homepage",
      description: "Cyber1101 | دروس وشروحات دوت نت عالم الخبرة الرقمية.",
      url: "\/?utm_source=homescreen",
      icons: [
          {
          src: "\/main\/home-icon-192x192.png",
          sizes: "192x192"
          }
        ]
      },
      {
      name: "احدث المشاركات",
      short_name: "Blog",
      description: "احدث المشاركات.",
      url: "\/search?utm_source=homescreen",
      icons: [
          {
          src: "\/main\/trend-icon-192x192.png",
          sizes: "192x192"
          }
        ]
      },
      {
      name: "تطبيقات والعاب",
      short_name: "تطبيقات والعاب",
      description: "التطبيقات والالعاب.",
      url: "\/search\/label\/تطبيقات?utm_source=homescreen",
      icons: [
          {
          src: "\/main\/appsm-icon-192x192.png",
          sizes: "192x192"
          }
        ]
      }
    ],
        screenshots: [
      {
      src: "\/main\/scr1.png",
      type: "image\/png",
      sizes: "540x720"
      },
      {
      src: "\/main\/scr2.png",
      type: "image\/png",
      sizes: "540x720"
      },
      {
      src: "\/main\/scr3.png",
      type: "image\/png",
      sizes: "540x720"
      },
      {
      src: "\/main\/scr4.png",
      type: "image\/png",
      sizes: "540x720"
      },
      {
      src: "\/main\/scr5.png",
      type: "image\/png",
      sizes: "540x720"
      }
    ],
    serviceworker: {
      src: "\/sw.js"
    }
  }

  const json = JSON.stringify(data, null, 2)

  return event.respondWith(
    new Response(json, {
      headers: {
        "content-type": "application/json;charset=UTF-8"
      }
    })
  )
})

استبدل الأجزاء المميزة بالون الاحمر حسب حاجتك. مع تغيير رمز اللون أيضًا. بعد انقر حفظ ونشر.

ServiceWorker

كما هو مذكور أعلاه ، أنشئ خدمة وأعد تسميتها serviceworker-blogname. استبدل الكود الموجود بالكود التالي:
const js = `
importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js');
if (workbox) {
workbox.core.skipWaiting();
workbox.core.clientsClaim();
workbox.core.setCacheNameDetails({
  prefix: 'thn-sw',
  suffix: 'v22',
  precache: 'install-time',
  runtime: 'run-time'
});

const FALLBACK_HTML_URL = '/offline.html';
const version = workbox.core.cacheNames.suffix;
workbox.precaching.precacheAndRoute([{url: FALLBACK_HTML_URL, revision: null},{url: '/manifest.json', revision: null},{url: '/main/favicon.ico', revision: null}]);

workbox.routing.setDefaultHandler(new workbox.strategies.NetworkOnly());

workbox.routing.registerRoute(
    new RegExp('.(?:css|js|png|gif|jpg|svg|ico)$'),
    new workbox.strategies.CacheFirst({
        cacheName: 'images-js-css-' + version,
        plugins: [
            new workbox.expiration.ExpirationPlugin({
                maxAgeSeconds: 60 * 24 * 60 * 60,
                maxEntries:200,
                purgeOnQuotaError: true
            })
        ],
    }),'GET'
);

workbox.routing.setCatchHandler(({event}) => {
      switch (event.request.destination) {
        case 'document':
        return caches.match(FALLBACK_HTML_URL);
      break;
      default:
        return Response.error();
  }
});

self.addEventListener('activate', function(event) {
  event.waitUntil(
    caches
      .keys()
      .then(keys => keys.filter(key => !key.endsWith(version)))
      .then(keys => Promise.all(keys.map(key => caches.delete(key))))
  );
});

}
else {
    console.log('Oops! Workbox did not load');
}
`

async function handleRequest(request) {
  return new Response(js, {
    headers: {
      "content-type": "application/javascript;charset=UTF-8",
    },
  })
}

addEventListener("fetch", event => {
  return event.respondWith(handleRequest(event.request))
})

لقد استخدمنا Workbox ، حتى نتمكن من تخزين HTML و CSS و JS وأي ملفات ثابتة مؤقتًا.
انقر فوق حفظ ونشر.

غير متصل بالانترنت Offline

كما هو مذكور أعلاه ، أنشئ خدمة وأعد تسميتها كـ offline-blogname، ie offline-medoapp.
استبدل الكود الموجود بالكود التالي:
  const html = `<!DOCTYPE html>
<html>

<head>
  <!--[ Meta Tags ]-->
  <title>Oops, You're Offline!</title>
  <meta charset='UTF-8'/>
  <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0' name='viewport'/>
  <meta content='IE=edge' http-equiv='X-UA-Compatible'/>

  <!--[ Theme Color ]-->
  <meta content='#BA0000' name='theme-color'/>
  <meta content='#BA0000' name='msapplication-navbutton-color'/>
  <meta content='#BA0000' name='apple-mobile-web-app-status-bar-style'/>
  <meta content='true' name='apple-mobile-web-app-capable'/>

  <!--[ Favicon ]-->
  <link href='/main/apple-icon-120x120.png' rel='apple-touch-icon' sizes='120x120'/>
  <link href='/main/apple-icon-152x152.png' rel='apple-touch-icon' sizes='152x152'/>
  <link href='/main/favicon-32x32.png' rel='icon' sizes='32x32' type='image/png'/>
  <link href='/main/favicon-96x96.png' rel='icon' sizes='96x96' type='image/png'/>
  <link href='/main/favicon-16x16.png' rel='icon' sizes='16x16' type='image/png'/>
  <link href='/main/favicon.ico' rel='icon' type='image/x-icon'/>
  <link href='/main/favicon.ico' rel='shortcut icon' type='image/x-icon'/>

  <!--[ Stylesheet ]-->
  <style>/*<![CDATA[*/
/* Merriweather - Font */ @font-face{font-family: 'Merriweather'; font-style: italic; font-weight: 300; font-display: swap; src: local('Merriweather-LightItalic'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4l0qyriQwlOrhSvowK_l5-eR7lXff4jvw.woff2) format('woff2'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4l0qyriQwlOrhSvowK_l5-eR7lXcf8.woff) format('woff')} @font-face{font-family: 'Merriweather'; font-style: italic; font-weight: 700; font-display: swap; src: url(https://fonts.gstatic.com/s/merriweather/v22/u-4l0qyriQwlOrhSvowK_l5-eR7NWPf4jvw.woff2) format('woff2'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4l0qyriQwlOrhSvowK_l5-eR71Wsf8.woff) format('woff')} @font-face{font-family: 'Merriweather'; font-style: italic; font-weight: 900; font-display: swap; src: url(https://fonts.gstatic.com/s/merriweather/v22/u-4l0qyriQwlOrhSvowK_l5-eR7NWPf4jvw.woff2) format('woff2'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4l0qyriQwlOrhSvowK_l5-eR7NWMf8.woff) format('woff')} @font-face{font-family: 'Merriweather'; font-style: normal; font-weight: 300; font-display: swap; src: url(https://fonts.gstatic.com/s/merriweather/v22/u-4n0qyriQwlOrhSvowK_l521wRZWMf6.woff2) format('woff2'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4n0qyriQwlOrhSvowK_l521wRpXA.woff) format('woff')} @font-face{font-family: 'Merriweather'; font-style: normal; font-weight: 700; font-display: swap; src: url(https://fonts.gstatic.com/s/merriweather/v22/u-4n0qyriQwlOrhSvowK_l52xwNZWMf6.woff2) format('woff2'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4n0qyriQwlOrhSvowK_l52xwNpXA.woff) format('woff')} @font-face{font-family: 'Merriweather'; font-style: normal; font-weight: 900; font-display: swap; src: url(https://fonts.gstatic.com/s/merriweather/v22/u-4n0qyriQwlOrhSvowK_l52_wFZWMf6.woff2) format('woff2'), url(https://fonts.gstatic.com/s/merriweather/v22/u-4n0qyriQwlOrhSvowK_l52_wFpXA.woff) format('woff')}
/* Content */ body{background:#f1f3f6;color:#1f1f1f;font-family:'Merriweather',serif;font-weight:400;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body:focus{outline:none !important} .mainCont{margin:0 auto;position:fixed;left:0;top:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;padding:15px} .noIntPop{position:relative;overflow:hidden;text-align:center;padding:15px;border-radius:30px;background:#f1f3f6;box-shadow:inset 0 0 15px rgba(55, 84, 170, 0), inset 0 0 20px rgba(255, 255, 255, 0), 7px 7px 15px rgba(55, 84, 170, 0.15), -7px -7px 20px white, inset 0px 0px 4px rgba(255, 255, 255, 0.2)} .circle.t{top:-150px;right:-150px} .circle.b{bottom:-150px;left:-150px} .noIntCont{position:relative;z-index:1} .noIntIcon{padding:30px} .noConHead{font-weight:700;font-size:1.3rem} .noConDesc{font-size:16px;line-height:1.4em;padding-top:20px;font-weight:400;opacity:.8} .cta,.relCont{display:flex;justify-content:center;align-items:center} .relCont{padding:30px} .cta{width:66px;height:66px;background:#f1f3f6;outline:none;border:none;border-radius:690px;box-shadow:inset 0 0 15px rgba(55, 84, 170, 0), inset 0 0 20px rgba(255, 255, 255, 0), 7px 7px 15px rgba(55, 84, 170, 0.15), -7px -7px 20px white, inset 0px 0px 4px rgba(255, 255, 255, 0.2);transition:box-shadow 399ms ease-in-out} .cta:hover{box-shadow:inset 7px 7px 15px rgba(55, 84, 170, 0.15), inset -7px -7px 20px white, 0px 0px 4px rgba(255, 255, 255, 0.2)} .icon{content:'';width:25px;height:25px;display:inline-block} .iconB{content:'';width:50px;height:50px;display:inline-block} .icon.reload{background:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239dabc0' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='23 4 23 10 17 10'/><path d='M20.49 15a9 9 0 1 1-2.12-9.36L23 10'/></svg>") center / 25px no-repeat} .iconB.wifiOff{background:url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231f1f1f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><line x1='1' y1='1' x2='23' y2='23'/><path d='M16.72 11.06A10.94 10.94 0 0 1 19 12.55'/><path d='M5 12.55a10.94 10.94 0 0 1 5.17-2.39'/><path d='M10.71 5.05A16 16 0 0 1 22.58 9'/><path d='M1.42 9a15.91 15.91 0 0 1 4.7-2.88'/><path d='M8.53 16.11a6 6 0 0 1 6.95 0'/><line x1='12' y1='20' x2='12.01' y2='20'/></svg>") center / 50px no-repeat} .circle{position:absolute;z-index:1;width:280px;height:280px;border-radius:50%;background-color:#f1f3f6;box-shadow:inset 8px 8px 12px #d1d9e6, inset -8px -8px 12px #f9f9f9}
  /*]]>*/</style>
</head>

<body>
  <div class='mainCont notranslate'>
    <div class='noIntPop'>
      <div class='circle t'></div>
      <div class='circle b'></div>
      <div class='noIntCont'>
        <div class='noIntIcon'>
          <i class='iconB wifiOff'></i>
        </div>
        <div class='noConHead'>Oops, You're Offline!</div>
        <div class='noConDesc'>يبدو أن هناك خطأ ما في اتصالك بالإنترنت..</div>

        <div class='relCont'>
          <button class='cta' onclick='window.location.reload()'>
            <i class='icon reload'></i>
          </button>
        </div>
      </div>
    </div>
  </div>
</body>

</html>`

async function handleRequest(request) {
  return new Response(html, {
    headers: {
      "content-type": "text/html;charset=UTF-8",
    },
  })
}

addEventListener("fetch", event => {
  return event.respondWith(handleRequest(event.request))
})

استبدل الأجزاء المميزة حسب رغبتك. انقر حفظ ونشر.

انشاء مسارات للخوادم Creating Routes

الآن اذهب إلى قسم العمال ثم انقر فوق إضافة مسار.
أدخل الحقول كما هو موضح في الجدول اسفل:
Route Service Environment
www.mr-medo.net/main/* main-medoapp production
www.mr-medo.net/manifest.json manifest-medoapp production
www.mr-medo.net/sw.js serviceworker-medoapp production
www.mr-medo.net/offline.html offline-medoapp production

أدخل الحقول حسب عنوان URL الخاص باسم مدونتك.

تحرير اكواد قالب المدونة

انتقل الآن إلى Blogger Dashboard.
انقر فوق تحرير HTML.
الصق الرموز التالية أدناه <head>، إذا لم تجدها ، فمن المحتمل أن يكون قد تم تحليلها وهو &lt;head&gt;. .
<link href='/main/apple-icon-57x57.png' rel='apple-touch-icon' sizes='57x57'/>
<link href='/main/apple-icon-60x60.png' rel='apple-touch-icon' sizes='60x60'/>
<link href='/main/apple-icon-72x72.png' rel='apple-touch-icon' sizes='72x72'/>
<link href='/main/apple-icon-76x76.png' rel='apple-touch-icon' sizes='76x76'/>
<link href='/main/apple-icon-114x114.png' rel='apple-touch-icon' sizes='114x114'/>
<link href='/main/apple-icon-120x120.png' rel='apple-touch-icon' sizes='120x120'/>
<link href='/main/apple-icon-114x114.png' rel='apple-touch-icon' sizes='144x144'/>
<link href='/main/apple-icon-152x152.png' rel='apple-touch-icon' sizes='152x152'/>
<link href='/main/apple-icon-180x180.png' rel='apple-touch-icon' sizes='180x180'/>
<link href='/main/android-icon-192x192.png' rel='icon' sizes='192x192' type='image/png'/>
<link href='/main/favicon-32x32.png' rel='icon' sizes='32x32' type='image/png'/>
<link href='/main/favicon-96x96.png' rel='icon' sizes='96x96' type='image/png'/>
<link href='/main/favicon-16x16.png' rel='icon' sizes='16x16' type='image/png'/>
<link href='/main/favicon.ico' rel='icon' type='image/x-icon'/>
<meta content='#BA0000' name='msapplication-TileColor'/>
<meta content='/main/ms-icon-144x144.png' name='msapplication-TileImage'/>
<meta content='#BA0000' name='theme-color'/>
<link href='/manifest.json' rel='manifest'/>

أضف كود Javascript التالي أعلاه </body>

<script>/*<![CDATA[*/
let deferredPrompt;
    window.addEventListener('beforeinstallprompt', (e) => {
        deferredPrompt = e;
    });

    const installApp = document.getElementById('installApp');
    installApp.addEventListener('click', async () => {
        if (deferredPrompt !== null) {
            deferredPrompt.prompt();
            const { outcome } = await deferredPrompt.userChoice;
            if (outcome === 'accepted') {
                deferredPrompt = null;
            }
        }
    });
/* Service Worker */ 
if('serviceWorker' in navigator){window.addEventListener('load',()=>{navigator.serviceWorker.register('/sw.js').then(registration=>{console.log('ServiceWorker registeration successful')}).catch(registrationError=>{console.log('ServiceWorker registration failed: ', registrationError)})})}; 
/*]]>*/</script>

وهذا زر استدعاء تحميل التطبيق يمكنك تضمينه في اي مكان تريد 

<button id="installApp">Install</button>

أتمنى أن تستمتع بهذه المقالة. PWA (تطبيق ويب تقدمي) لموقع الويب الخاص بك على Blogger. وإذا كنت تواجه مشكلة أو كان لديك أي سؤال ، فاسألنا في مربع التعليقات . شكرًا لكم !

المصدر:-
www.fineshopdesign.com

ينتهي هنا موضوعنا عن "كيفية إنشاء تطبيق ويب تقدمي PWA لمدونات بلوجر"، ونلتقي في موضوع جديد على مدونة Cyber1101. دمتم في امان الله :)

تقييم المقالة

إرسال تعليق

Cookie Consent
We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.