django-pwa


Namedjango-pwa JSON
Version 2.0.0 PyPI version JSON
download
home_pageNone
SummaryA Django app to include a manifest.json and Service Worker instance to enable progressive web app behavior
upload_time2024-07-18 19:18:53
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT License (MIT) Copyright (c) 2014 Scott Vitale, Silvio Luis and Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            django-pwa
=====
[![Build Status](https://travis-ci.org/silviolleite/django-pwa.svg)](https://travis-ci.org/silviolleite/django-pwa)
[![Maintainability](https://api.codeclimate.com/v1/badges/246542ea921058c4f76f/maintainability)](https://codeclimate.com/github/silviolleite/django-pwa/maintainability)
[![codecov](https://codecov.io/gh/silviolleite/django-pwa/branch/master/graph/badge.svg)](https://codecov.io/gh/silviolleite/django-pwa)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/django-pwa.svg)](https://pypi.org/project/django-pwa/)
[![PyPI - Downloads](https://img.shields.io/pypi/v/django-pwa.svg)](https://pypi.org/project/django-pwa)
[![PyPI - Downloads](https://img.shields.io/pypi/djversions/django-pwa.svg)](https://pypi.org/project/django-pwa)

This Django app turns your project into a [progressive web app](https://developers.google.com/web/progressive-web-apps/).  Navigating to your site on an Android phone will prompt you to add the app to your home screen.

![Prompt for install](https://github.com/silviolleite/django-pwa/raw/master/images/screenshot1.png)

Launching the app from your home screen will display your app [without browser chrome](https://github.com/silviolleite/django-pwa/raw/master/images/screenshot2.png).  As such, it's critical that your application provides all navigation within the HTML (no reliance on the browser back or forward button).

Requirements
=====
Progressive Web Apps require HTTPS unless being served from localhost.  If you're not already using HTTPS on your site, check out [Let's Encrypt](https://letsencrypt.org/) and [ZeroSSL](https://zerossl.com/).

Installation
=====
Install from PyPI:

```
pip install django-pwa
```

Configuration
=====
Add `pwa` to your list of `INSTALLED_APPS` in settings.py:

```python
INSTALLED_APPS = [
    ...
    'pwa',
    ...
]
```
Define STATICFILES_DIRS for your custom PWA_APP_ICONS
```python
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]
```

Configure your app name, description, icons, splash screen images, screenshots and shortcuts in settings.py:
```python

PWA_APP_NAME = 'My App'
PWA_APP_DESCRIPTION = "My app description"
PWA_APP_THEME_COLOR = '#0A0302'
PWA_APP_BACKGROUND_COLOR = '#ffffff'
PWA_APP_DISPLAY = 'standalone'
PWA_APP_SCOPE = '/'
PWA_APP_ORIENTATION = 'any'
PWA_APP_START_URL = '/'
PWA_APP_STATUS_BAR_COLOR = 'default'
PWA_APP_ICONS = [
    {
        'src': '/static/images/my_app_icon.png',
        'sizes': '160x160'
    }
]
PWA_APP_ICONS_APPLE = [
    {
        'src': '/static/images/my_apple_icon.png',
        'sizes': '160x160'
    }
]
PWA_APP_SPLASH_SCREEN = [
    {
        'src': '/static/images/icons/splash-640x1136.png',
        'media': '(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)'
    }
]
PWA_APP_DIR = 'ltr'
PWA_APP_LANG = 'en-US'
PWA_APP_SHORTCUTS = [
    {
        'name': 'Shortcut',
        'url': '/target',
        'description': 'Shortcut to a page in my application'
    }
]
PWA_APP_SCREENSHOTS = [
    {
      'src': '/static/images/icons/splash-750x1334.png',
      'sizes': '750x1334',
      "type": "image/png"
    }
]

```
#### Show console.log
Set the `PWA_APP_DEBUG_MODE = False` to disable the the `console.log` on browser.

All settings are optional, and the app will work fine with its internal defaults.  Highly recommend setting at least `PWA_APP_NAME`, `PWA_APP_DESCRIPTION`, `PWA_APP_ICONS` and `PWA_APP_SPLASH_SCREEN`.
In order to not use one of the internal defaults, a setting can be set to an empty string or list, whichever one is applicable.

Add the progressive web app URLs to urls.py:
```python
from django.urls import url, include

urlpatterns = [
    ...
    url('', include('pwa.urls')),  # You MUST use an empty string as the URL prefix
    ...
]
```

Inject the required meta tags in your base.html (or wherever your HTML <head> is defined):
```html
{% load pwa %}

<head>
    ...
    {% progressive_web_app_meta %}
    ...
</head>
```

Troubleshooting
=====
While running the Django test server:

1. Verify that `/manifest.json` is being served
2. Verify that `/serviceworker.js` is being served
3. Verify that `/offline` is being served
4. Use the Application tab in the Chrome Developer Tools to verify the progressive web app is configured correctly.
5. Use the "Add to homescreen" link on the Application Tab to verify you can add the app successfully.


The Service Worker
=====
By default, the service worker implemented by this app is:
```js
// Base Service Worker implementation.  To use your own Service Worker, set the PWA_SERVICE_WORKER_PATH variable in settings.py

var staticCacheName = "django-pwa-v" + new Date().getTime();
var filesToCache = [
    '/offline',
    '/css/django-pwa-app.css',
    '/images/icons/icon-72x72.png',
    '/images/icons/icon-96x96.png',
    '/images/icons/icon-128x128.png',
    '/images/icons/icon-144x144.png',
    '/images/icons/icon-152x152.png',
    '/images/icons/icon-192x192.png',
    '/images/icons/icon-384x384.png',
    '/images/icons/icon-512x512.png',
    '/static/images/icons/splash-640x1136.png',
    '/static/images/icons/splash-750x1334.png',
    '/static/images/icons/splash-1242x2208.png',
    '/static/images/icons/splash-1125x2436.png',
    '/static/images/icons/splash-828x1792.png',
    '/static/images/icons/splash-1242x2688.png',
    '/static/images/icons/splash-1536x2048.png',
    '/static/images/icons/splash-1668x2224.png',
    '/static/images/icons/splash-1668x2388.png',
    '/static/images/icons/splash-2048x2732.png'
];

// Cache on install
self.addEventListener("install", event => {
    this.skipWaiting();
    event.waitUntil(
        caches.open(staticCacheName)
            .then(cache => {
                return cache.addAll(filesToCache);
            })
    )
});

// Clear cache on activate
self.addEventListener('activate', event => {
    event.waitUntil(
        caches.keys().then(cacheNames => {
            return Promise.all(
                cacheNames
                    .filter(cacheName => (cacheName.startsWith("django-pwa-")))
                    .filter(cacheName => (cacheName !== staticCacheName))
                    .map(cacheName => caches.delete(cacheName))
            );
        })
    );
});

// Serve from Cache
self.addEventListener("fetch", event => {
    event.respondWith(
        caches.match(event.request)
            .then(response => {
                return response || fetch(event.request);
            })
            .catch(() => {
                return caches.match('offline');
            })
    )
});
```

Adding Your Own Service Worker
=====
To add service worker functionality, you'll want to create a `serviceworker.js` or similarly named template in a template directory, and then point at it using the PWA_SERVICE_WORKER_PATH variable (PWA_APP_FETCH_URL is passed through).

```python
PWA_SERVICE_WORKER_PATH = os.path.join(BASE_DIR, 'my_app', 'serviceworker.js')

```

The offline view
=====
By default, the offline view is implemented in `templates/offline.html`
You can overwrite it in a template directory if you continue using the default `serviceworker.js`.


Feedback
=====
I welcome your feedback and pull requests.  Enjoy!

License
=====
All files in this repository are distributed under the MIT license.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "django-pwa",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": "Christian Hartung <hartungstenio@outlook.com>",
    "keywords": null,
    "author": null,
    "author_email": "Silvio Luis <silviolleite@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/08/4b/340f5c8623c46cccf6412df122ebbd4a351a737c20a38d3ea5774216d386/django_pwa-2.0.0.tar.gz",
    "platform": null,
    "description": "django-pwa\n=====\n[![Build Status](https://travis-ci.org/silviolleite/django-pwa.svg)](https://travis-ci.org/silviolleite/django-pwa)\n[![Maintainability](https://api.codeclimate.com/v1/badges/246542ea921058c4f76f/maintainability)](https://codeclimate.com/github/silviolleite/django-pwa/maintainability)\n[![codecov](https://codecov.io/gh/silviolleite/django-pwa/branch/master/graph/badge.svg)](https://codecov.io/gh/silviolleite/django-pwa)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/django-pwa.svg)](https://pypi.org/project/django-pwa/)\n[![PyPI - Downloads](https://img.shields.io/pypi/v/django-pwa.svg)](https://pypi.org/project/django-pwa)\n[![PyPI - Downloads](https://img.shields.io/pypi/djversions/django-pwa.svg)](https://pypi.org/project/django-pwa)\n\nThis Django app turns your project into a [progressive web app](https://developers.google.com/web/progressive-web-apps/).  Navigating to your site on an Android phone will prompt you to add the app to your home screen.\n\n![Prompt for install](https://github.com/silviolleite/django-pwa/raw/master/images/screenshot1.png)\n\nLaunching the app from your home screen will display your app [without browser chrome](https://github.com/silviolleite/django-pwa/raw/master/images/screenshot2.png).  As such, it's critical that your application provides all navigation within the HTML (no reliance on the browser back or forward button).\n\nRequirements\n=====\nProgressive Web Apps require HTTPS unless being served from localhost.  If you're not already using HTTPS on your site, check out [Let's Encrypt](https://letsencrypt.org/) and [ZeroSSL](https://zerossl.com/).\n\nInstallation\n=====\nInstall from PyPI:\n\n```\npip install django-pwa\n```\n\nConfiguration\n=====\nAdd `pwa` to your list of `INSTALLED_APPS` in settings.py:\n\n```python\nINSTALLED_APPS = [\n    ...\n    'pwa',\n    ...\n]\n```\nDefine STATICFILES_DIRS for your custom PWA_APP_ICONS\n```python\nSTATICFILES_DIRS = [\n    os.path.join(BASE_DIR, 'static'),\n]\n```\n\nConfigure your app name, description, icons, splash screen images, screenshots and shortcuts in settings.py:\n```python\n\nPWA_APP_NAME = 'My App'\nPWA_APP_DESCRIPTION = \"My app description\"\nPWA_APP_THEME_COLOR = '#0A0302'\nPWA_APP_BACKGROUND_COLOR = '#ffffff'\nPWA_APP_DISPLAY = 'standalone'\nPWA_APP_SCOPE = '/'\nPWA_APP_ORIENTATION = 'any'\nPWA_APP_START_URL = '/'\nPWA_APP_STATUS_BAR_COLOR = 'default'\nPWA_APP_ICONS = [\n    {\n        'src': '/static/images/my_app_icon.png',\n        'sizes': '160x160'\n    }\n]\nPWA_APP_ICONS_APPLE = [\n    {\n        'src': '/static/images/my_apple_icon.png',\n        'sizes': '160x160'\n    }\n]\nPWA_APP_SPLASH_SCREEN = [\n    {\n        'src': '/static/images/icons/splash-640x1136.png',\n        'media': '(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)'\n    }\n]\nPWA_APP_DIR = 'ltr'\nPWA_APP_LANG = 'en-US'\nPWA_APP_SHORTCUTS = [\n    {\n        'name': 'Shortcut',\n        'url': '/target',\n        'description': 'Shortcut to a page in my application'\n    }\n]\nPWA_APP_SCREENSHOTS = [\n    {\n      'src': '/static/images/icons/splash-750x1334.png',\n      'sizes': '750x1334',\n      \"type\": \"image/png\"\n    }\n]\n\n```\n#### Show console.log\nSet the `PWA_APP_DEBUG_MODE = False` to disable the the `console.log` on browser.\n\nAll settings are optional, and the app will work fine with its internal defaults.  Highly recommend setting at least `PWA_APP_NAME`, `PWA_APP_DESCRIPTION`, `PWA_APP_ICONS` and `PWA_APP_SPLASH_SCREEN`.\nIn order to not use one of the internal defaults, a setting can be set to an empty string or list, whichever one is applicable.\n\nAdd the progressive web app URLs to urls.py:\n```python\nfrom django.urls import url, include\n\nurlpatterns = [\n    ...\n    url('', include('pwa.urls')),  # You MUST use an empty string as the URL prefix\n    ...\n]\n```\n\nInject the required meta tags in your base.html (or wherever your HTML &lt;head&gt; is defined):\n```html\n{% load pwa %}\n\n<head>\n    ...\n    {% progressive_web_app_meta %}\n    ...\n</head>\n```\n\nTroubleshooting\n=====\nWhile running the Django test server:\n\n1. Verify that `/manifest.json` is being served\n2. Verify that `/serviceworker.js` is being served\n3. Verify that `/offline` is being served\n4. Use the Application tab in the Chrome Developer Tools to verify the progressive web app is configured correctly.\n5. Use the \"Add to homescreen\" link on the Application Tab to verify you can add the app successfully.\n\n\nThe Service Worker\n=====\nBy default, the service worker implemented by this app is:\n```js\n// Base Service Worker implementation.  To use your own Service Worker, set the PWA_SERVICE_WORKER_PATH variable in settings.py\n\nvar staticCacheName = \"django-pwa-v\" + new Date().getTime();\nvar filesToCache = [\n    '/offline',\n    '/css/django-pwa-app.css',\n    '/images/icons/icon-72x72.png',\n    '/images/icons/icon-96x96.png',\n    '/images/icons/icon-128x128.png',\n    '/images/icons/icon-144x144.png',\n    '/images/icons/icon-152x152.png',\n    '/images/icons/icon-192x192.png',\n    '/images/icons/icon-384x384.png',\n    '/images/icons/icon-512x512.png',\n    '/static/images/icons/splash-640x1136.png',\n    '/static/images/icons/splash-750x1334.png',\n    '/static/images/icons/splash-1242x2208.png',\n    '/static/images/icons/splash-1125x2436.png',\n    '/static/images/icons/splash-828x1792.png',\n    '/static/images/icons/splash-1242x2688.png',\n    '/static/images/icons/splash-1536x2048.png',\n    '/static/images/icons/splash-1668x2224.png',\n    '/static/images/icons/splash-1668x2388.png',\n    '/static/images/icons/splash-2048x2732.png'\n];\n\n// Cache on install\nself.addEventListener(\"install\", event => {\n    this.skipWaiting();\n    event.waitUntil(\n        caches.open(staticCacheName)\n            .then(cache => {\n                return cache.addAll(filesToCache);\n            })\n    )\n});\n\n// Clear cache on activate\nself.addEventListener('activate', event => {\n    event.waitUntil(\n        caches.keys().then(cacheNames => {\n            return Promise.all(\n                cacheNames\n                    .filter(cacheName => (cacheName.startsWith(\"django-pwa-\")))\n                    .filter(cacheName => (cacheName !== staticCacheName))\n                    .map(cacheName => caches.delete(cacheName))\n            );\n        })\n    );\n});\n\n// Serve from Cache\nself.addEventListener(\"fetch\", event => {\n    event.respondWith(\n        caches.match(event.request)\n            .then(response => {\n                return response || fetch(event.request);\n            })\n            .catch(() => {\n                return caches.match('offline');\n            })\n    )\n});\n```\n\nAdding Your Own Service Worker\n=====\nTo add service worker functionality, you'll want to create a `serviceworker.js` or similarly named template in a template directory, and then point at it using the PWA_SERVICE_WORKER_PATH variable (PWA_APP_FETCH_URL is passed through).\n\n```python\nPWA_SERVICE_WORKER_PATH = os.path.join(BASE_DIR, 'my_app', 'serviceworker.js')\n\n```\n\nThe offline view\n=====\nBy default, the offline view is implemented in `templates/offline.html`\nYou can overwrite it in a template directory if you continue using the default `serviceworker.js`.\n\n\nFeedback\n=====\nI welcome your feedback and pull requests.  Enjoy!\n\nLicense\n=====\nAll files in this repository are distributed under the MIT license.\n",
    "bugtrack_url": null,
    "license": "MIT License (MIT)  Copyright (c) 2014 Scott Vitale, Silvio Luis and Contributors  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
    "summary": "A Django app to include a manifest.json and Service Worker instance to enable progressive web app behavior",
    "version": "2.0.0",
    "project_urls": {
        "Repository": "http://github.com/silviolleite/django-pwa"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "da246df7754339504e35c2f38e43a5215e98e1debce11bd23e6148f0e8005d40",
                "md5": "1a7ed2c1a3badb8a541203734cbaa80c",
                "sha256": "7b185cc8ab113c75468dc65a4a2cd9f63e35854c895e3b1bb60fe8d902c0272f"
            },
            "downloads": -1,
            "filename": "django_pwa-2.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "1a7ed2c1a3badb8a541203734cbaa80c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 453982,
            "upload_time": "2024-07-18T19:18:51",
            "upload_time_iso_8601": "2024-07-18T19:18:51.893707Z",
            "url": "https://files.pythonhosted.org/packages/da/24/6df7754339504e35c2f38e43a5215e98e1debce11bd23e6148f0e8005d40/django_pwa-2.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "084b340f5c8623c46cccf6412df122ebbd4a351a737c20a38d3ea5774216d386",
                "md5": "052e85cf48746e28119d087795d425cf",
                "sha256": "489532e2b742c69b19de529c7c422d7a98911645932ea05ea7e4fd43b4757b0d"
            },
            "downloads": -1,
            "filename": "django_pwa-2.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "052e85cf48746e28119d087795d425cf",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 448236,
            "upload_time": "2024-07-18T19:18:53",
            "upload_time_iso_8601": "2024-07-18T19:18:53.445308Z",
            "url": "https://files.pythonhosted.org/packages/08/4b/340f5c8623c46cccf6412df122ebbd4a351a737c20a38d3ea5774216d386/django_pwa-2.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-07-18 19:18:53",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "silviolleite",
    "github_project": "django-pwa",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "lcname": "django-pwa"
}
        
Elapsed time: 0.24264s