NAME
Progressive::Web::Application - Utility for making an application 'progressive'
VERSION
Version 0.06
SYNOPSIS
# vim MyApp/pwa.pl
use Progressive::Web::Application;
my $pwa = Progressive::Web::Application->new({
root => 'root',
pathpart => 'payments',
manifest => {
name => 'Progressive Web Application Demo',
short_name => 'PWA Demo',
icons => '/root/static/images/icons',
start_url => '/',
display => 'standalone',
background_color => '#2b3e50',
theme_color => '#2c3e50'
},
params => {
offline_path => '/offline.html',
cache_name => 'my-cache-name',
files_to_cache => [
'/manifest.json',
'/favicon.ico',
'/static/css/bootstrap.min.css',
'/static/css/lnation.css',
...
],
}
});
$pwa->compile();
...
DESCRIPTION
This module is a Utility for aiding you in creating Progressive Web Applications (PWA's). Progressive web apps use modern browser APIs along with traditional progressive enhancement strategy to create cross-platform applications. These apps work everywhere that a browser runs and provide several features that give them the same user experience advantages as native apps.
PWAs should be discoverable, installable, linkable, network independent, progressive, re-engageable, responsive, and safe.
Discoverable
The eventual aim is that web apps should have better representation in search engines, be easier to expose, catalog and rank, and have metadata usable by browsers to give them special capabilities.
Installable
A core part of the apps experience is for users to have app icons on their home screen, that launch in a native container that feels integrated with the underlying platform.
Linkable
One of the most powerful features of the Web is to be able to link to an app at a specific URL - no app store needed, no complex installation process. This is how it has always been.
Network Independent
Can work when the network is unreliable, or even non-existent.
Progressive
Can be developed to provide a modern experience to fully capable browsers, and an acceptable (although not quite as shiny) experience in less capable browsers.
Re-engageable
One major advantage of native platforms is the ease with which users can be re-engaged by updates and new content, even when they aren't looking at the app or using their devices. Modern Web APIs allow us to do this too, using new technologies such as Service Workers for controlling pages, the Web Push API for sending updates straight from server to app via a service worker, and the Notifications API for generating system notifications to help engage users when they're not in the browser.
Responsive
Responsive web apps use technologies like media queries and viewport to make sure that their UIs will fit any form factor: desktop, mobile, tablet, or whatever comes next.
Safe
You can verify the true nature of a PWA by confirming that it is at the correct URL, whereas apps in apps stores can often look like one thing, but be another. Example - https://twitter.com/andreasbovens/status/926965095296651264
Methods
new
Instantiate a new Progressive::Web::Application Object.
Progressive::Web::Application->new();
options
root
The root(/) directory of your application, this is used to validate links and where any output from this module will be compiled/written.
lnation:High lnation$ ls
MyApp
.......
Progressive::Web::Application->new(
root => 'MyApp/root'
);
pathpart
Is your application proxied to a path.
https://localhost/admin/*
.......
Progressive::Web::Application->new(
pathpart => 'admin'
);
manifest
A Hash reference of params to build the web app manifest. See manifest_schema for more information.
Progressive::Web::Application->new(
manifest => {
name => 'Progressive Web Application Demo',
short_name => 'PWA Demo',
icons => '/root/static/images/icons',
start_url => '/',
display => 'standalone',
background_color => '#2b3e50',
theme_color => '#2c3e50'
},
);
template
A string that represents a template class. See Progressive::Web::Application::Template namespace for options.
Progressive::Web::Application->new(
template => 'General' # the default
);
params
A Hash reference of params that are passed into the template. These are dynamic based upon the selected template so check the documentation for more information on what is required. However the following have some addtional logic to aide you.
- cache_name
-
All templates will have a cache name, it is used to keep track of the version of the cache. Each release that has resource changes will require an update to the cache_name. This ensures your end users service workers clears the existing cache and re-fetch's the resources from your server.
Progressive::Web::Application->new( params => { cache_name => 'my_cache_name_v2' } );
- files_to_cache
-
You can pass in as an Array reference, Hash reference or Code block.
ARRAY - expects a list of files to be cached
Progressive::Web::Application->new( params => { files_to_cache => [ 'resources/css/app.css', 'resources/js/app.js', ... ] } );
HASH - params to be passed to $pwa->tools->{identify_files_to_cache}, see documentation for more information.
Progressive::Web::Application->new( params => { files_to_cache => { directory => 'root/static', recurse => 1 } } );
CODE - a custom code block that returns an Array references of files to cache.
Progressive::Web::Application->new( params => { files_to_cache => sub { my $tool = @_; my @files = ( $tool->{read_directory}->('root/static/js'), $tool->{read_directory}->('root/static/css'), ); ... return \@files; } } );
set_template
Set the template class.
$pwa->set_template(template => 'General');
set_pathpart
Set the pathpart of your application.
$pwa->set_pathpart('somepath');
set_root
Set the root directory of your application.
$pwa->set_root('MyApp/root');
has_manifest
Does the Progressive::Web::Applcation object have a manifest configured, returns true or false value (1|0).
$pwa->has_manifest();
manifest
Return the configured manifest, if a true param is passed then this is returned as json.
$pwa->manifest(1);
set_manifest
Set the manifest params see manifest_schema for full options.
$pwa->set_manifest(
name => 'Progressive Web Application Demo',
short_name => 'PWA Demo',
icons => '/root/static/images/icons',
start_url => '/',
display => 'standalone',
background_color => '#2b3e50',
theme_color => '#2c3e50'
);
clear_manifest
Clear/Delete manifest from the object, this is usefull for when you call 'compile' to different outpaths multiple times within a script.
$pwa->clear_manifest();
has_params
Does the Progressive::Web::Application have params configured, returns true or false value (1|0).
$pwa->has_params();
params
Return the configured manifest, if a true param is passed then this is returned as json.
$pwa->params(1);
set_params
Set the template params see the configured template for what is required.
$pwa->set_params(
offline_path => '/offline.html',
cache_name => 'my-cache-name',
files_to_cache => [
'/manifest.json',
'/favicon.ico',
'/static/css/bootstrap.min.css',
'/static/css/lnation.css',
...
],
);
clear_params
Clear/Delete params from the object, this is usefull for when you call 'compile' to different outpaths multiple times within a script.
$pwa->clear_params();
template
Returns the template object.
$pwa->template();
templates
Returns the rendered templates as a hash reference.
$pwa->templates();
compile
This will write the manifest.json and any templates configured in the Template class into the root directory. You can optionally pass in a different path for the resources to be written.
$pwa->compile();
...
$pwa->compile('MyApp/root/resources');
manifest_schema
name
Scalar - The applications 'full' name.
$pwa->set_manifest(name => 'My Application Name');
The name member is a string that represents the name of the web application as it is usually displayed to the user (e.g., amongst a list of other applications, or as a label for an icon). name is directionality-capable, which means it can be displayed left-to-right or right-to-left based on the values of the dir and lang manifest members.
https://developer.mozilla.org/en-US/docs/Web/Manifest/name
short_name
Scalar - The applications 'abbreviation' name
$pwa->set_manifest(short_name => 'MyApp');
The short_name member is a string that represents the name of the web application displayed to the user if there is not enough space to display name (e.g., as a label for an icon on the phone home screen). short_name is directionality-capable, which means it can be displayed left-to-right or right-to-left based on the value of the dir and lang manifest members.
https://developer.mozilla.org/en-US/docs/Web/Manifest/short_name
description
Scalar - Description of the application.
$pwa->set_manifest(description => 'A description about my application');
The description member is a string in which developers can explain what the application does. description is directionality-capable, which means it can be displayed left to right or right to left based on the values of the dir and lang manifest members.
https://developer.mozilla.org/en-US/docs/Web/Manifest/description
lang
Scalar - Language of the application
$pwa->set_manifest(lang => 'en-GB');
The lang member is a string containing a single language tag (https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang). It specifies the primary language for the values of the manifest's directionality-capable members, and together with dir determines their directionality.
https://developer.mozilla.org/en-US/docs/Web/Manifest/lang
dir
Scalar - Direction of Lang (auto|ltr|rtl)
$pwa->set_manifest(dir => 'ltr');
The base direction in which to display direction-capable members of the manifest. Together with the lang member, it helps to correctly display right-to-left languages.
https://developer.mozilla.org/en-US/docs/Web/Manifest/dir
orientation
Scalar - orientation of the screen (any|natural|landscape|landscape-primary|landscape-secondary|portrait|portrait-primary|portrait-secondary)
$pwa->set_manifest(orientation => 'natural');
The orientation member defines the default orientation for all the website's top-level browsing contexts. The orientation can be changed at runtime via the Screen Orientation API (https://developer.mozilla.org/en-US/docs/Web/API/Screen/orientation)
https://developer.mozilla.org/en-US/docs/Web/Manifest/orientation
prefer_related_applications
Boolean - Prefer a related web application to recommend to 'install'.
$pwa->set_manifest(prefer_related_applications => \1)
The prefer_related_applications member is a boolean value that specifies that applications listed in related_applications should be preferred over the web application. If the prefer_related_applications member is set to true, the user agent might suggest installing one of the related applications instead of this web app.
https://developer.mozilla.org/en-US/docs/Web/Manifest/prefer_related_applications
related_applications
ArrayRef - A list of related application to recommend
$pwa->set_manifest(related_applications => [
{
platform => "play",
url => "https://play.google.com/store/apps/details?id=com.example.app1",
id => "com.example.app1"
}
]);
The related_applications field is an array of objects specifying native applications that are installable by, or accessible to, the underlying platform - for example, a native Android application obtainable through the Google Play Store. Such applications are intended to be alternatives to the manifest's website that provides similar/equivalent functionality - like the native app equivalent.
https://developer.mozilla.org/en-US/docs/Web/Manifest/related_applications
iarc_rating_id
Scalar - International Age Rating Coalition (IARC) certification code
$pwa->set_manifest(iarc_rating_id => 'e84b072d-71b3-4d3e-86ae-31a8ce4e53b7');
The iarc_rating_id member is a string that represents the International Age Rating Coalition (https://www.globalratings.com) certification code of the web application. It is intended to be used to determine which ages the web application is appropriate for.
https://developer.mozilla.org/en-US/docs/Web/Manifest/iarc_rating_id
scope
Scalar - Applications scope
$pwa->set_manifest(scope => '/app/');
The scope member is a string that defines the navigation scope of this web application's application context. It restricts what web pages can be viewed while the manifest is applied. If the user navigates outside the scope, it reverts to a normal web page inside a browser tab or window.
https://developer.mozilla.org/en-US/docs/Web/Manifest/scope
screenshots
ArrayRef - Application screenshot previews
$pwa->set_manifest(screenshots => [
{
src => "screenshot1.webp",
sizes => "1280x720",
type => "image/webp"
}
]);
The screenshots member defines an array of screenshots intended to showcase the application. These images are intended to be used by progressive web app stores.
https://developer.mozilla.org/en-US/docs/Web/Manifest/screenshots
categories
ArrayRef - Application categories
$pwa->set_manifest(categories => [
"finance"
]);
The categories member is an array of strings defining the names of categories that the application supposedly belongs to. There is no standard list of possible values, but the W3C maintains a list of known categories. (https://github.com/w3c/manifest/wiki/Categories)
https://developer.mozilla.org/en-US/docs/Web/Manifest/categories
start_url
Scalar - Start path the application will launch
$pwa->set_manifest(start_url => '/home');
The start_url member is a string that represents the start URL of the web application - the prefered URL that should be loaded when the user launches the web application (e.g., when the user taps on the web application's icon from a device's application menu or homescreen).
https://developer.mozilla.org/en-US/docs/Web/Manifest/start_url
icons
Scalar - a directory path passed into $TOOL{identify_icon_information}
$pwa->set_manifest(icons => 'root/static/images/icons');
HashRef - generate_icons or validate hash as an icon.
$pwa->set_manifest(icons => {
file => 'root/static/images/320x320-icon.png',
outpath => 't/resources/icons',
});
...
$pwa->set_manidest(icons => {
sizes => '310x310',
src => '/t/resources/320x320-icon.png',
type => 'image/png'
});
Code - Custom coderef that returns an array of icons
$pwa->set_manidest(icons => sub {
my $tool = shift;
});
ArrayRef - itterate Scalar/Hash/Code
The icons member specifies an array of objects representing image files that can serve as application icons for different contexts. For example, they can be used to represent the web application amongst a list of other applications, or to integrate the web application with an OS's task switcher and/or system preferences.
https://developer.mozilla.org/en-US/docs/Web/Manifest/icons
display
Scalar - Browser display mode (standalone|minimal-ui|fullscreen|browser)
The display member is a string that determines the developers preferred display mode for the website. The display mode changes how much of browser UI is shown to the user and can range from "browser" (when the full browser window is shown) to "fullscreen" (when the app is full-screened).
https://developer.mozilla.org/en-US/docs/Web/Manifest/display
background_color
Scalar - Background colour
The background_color member defines a placeholeder background color for the application page to display before its stylesheet is loaded. This value is used by the user agent to draw the background color of a shortcut when the manifest is available before the stylesheet has loaded.
https://developer.mozilla.org/en-US/docs/Web/Manifest/background_color
theme_color
Scalar - Theme colour
The theme_color member is a string that defines the default theme color for the application. This sometimes affects how the OS displays the site (e.g., on Android's task switcher, the theme color surrounds the site).
https://developer.mozilla.org/en-US/docs/Web/Manifest/theme_color
tools
tainted
Returns a regex used to make paths/files taint safe.
my $filename =~ $tools->{tainted};
$1 # taint safe *\o/*
array_check
Validate the param is an Array, returns the param if valid and it will die/croak if invalid.
my $arrayref = [qw/a b c/];
$tool->{array_check}->($arrayref);
scalar_check
Validate the param is a Scalar (not a scalar reference), return the param if vaid and it will die/croak if invalid.
my $string = 'abc';
$tool->{scalar_check}->($string);
colour_check
Validate the param is a valid colour, returns the param if valid and it will die/croak if invalid.
my $colour = '#000';
$tool->{colour_check}->($colour);
JSON
Returns a JSON object with 'pretty' mode turned on.
$tool->{JSON}->encode($ref);
to_json
Encodes the passed param as JSON.
my $ref = { a => 'b' };
$tool->{to_json}->($ref);
from_json
Decodes the passed json into a perl struct.
my $json = q|{"a":"b"}|;
$tool->{from_json}->($ref);
make_path
Creates the path in the file system.
$tool->{make_path}->('root/static/new/path');
remove_abs
Removes the absolute path from a file path.
my $path = '/var/www/MyApp/root/static/images/icon/one.png';
my $relative = $tool->{remove_abs}->($path);
# 'root/static/images/icon/one.png'
abs
Converts a relative path into an absolute path.
my $rel = 'root/static/images/icon/one.png';
my $abs = $tool->{abs}->($rel);
# '/var/www/MyApp/root/static/images/icon/one.png'
write_file
Creates/Writes a file.
$tool->{write_file}->('root/static/images/icons/two.png', $png_data);
read_file
Reads a file into memory.
$tool->{read_file}->('root/static/images/icons/two.png');
remove_file
Removes/Deletes a file.
$tool->{remove_file}->('root/static/images/icons/two.png');
read_directory
Reads a directory into an array of filenames. First argument should be the directory path, you can optionally pass the following options.
- recurse
-
Boolean to determine whether directories within the passed directory should be recursed.
- blacklist_regex
-
A blacklist regex which will skip file paths that match it.
- whitelist_regex
-
A whitelist regex which will skip file paths that do not match it.
$tool->{read_directory}->('root/static',
recurse => 1,
blacklist_regex => qr/documentation/
);
remove_directory
Removes/Deletes a directory.
$tool->{remove_directory}->('root/static/images/icons');
valid_icon_sizes
Returns an Hash reference of known valid icon sizes, this is to cater for the various devices your application may be installed on.
$tool->{valid_icon_sizes}->{'36x36'}; # valid
$tool->{valid_icon_sizes}->{'1000x1000'}; # invalid
vaid_icon_types
Returns an Hash reference of currently supported icon types.
$tool->{valid_icon_types}->{'image/png'};
generate_icons
Accepts an path to an icon and generates an icon for each of the valid_icon_sizes. You can optionally pass the following options.
- outpath
-
The directory the icons will be generated/written too (default is the directory of the original icon).
- icon_name
-
The suffix that will applied to the icon name (default is 'icon')
$tool->{generate_icons}->('root/static/images/one.png',
outpath => 'root/static/images/icons'
);
identify_icon_size
Identify an icons size and validate tagains valid_icon_sizes.
$tool->{identify_icon_size}->('root/static/images/icon/my-icon.png');
identify_icon_information
Identify icon information from a passed file.
$tool->{identify_icon_size}->('root', 'root/static/images/icon/my-icon.png');
# {
# src => '/static/images/icon/my-icon.png',
# type => 'image/png',
# sizes => '36x36'
# }
validate_icon_information
Validate a passed hashref is a valid 'icon' definition.
my $icon = {
src => '/static/images/icon/my-icon.png',
type => 'image/png',
sizes => '36x36'
};
$tool->{validate_icon_information}->($icon);
parse_params
Parse params, from a hash reference into a hash 'list'.
my ($self, %hash) = $tool->{parse_params}->($self, { a => "b" });
my ($self, %hash) = $tool->{parse_params}->($self, a => "b");
identify_files_to_cache
Returns a list of files/resources to cache. Accepts a directory or an Arrayref of directorys and optionally params that are passed to $tool{reaD_directory} see documentation for more information.
my @files_to_cache = $tool->{identify_files_to_cache}->([
'root/static/js',
'root/static/css',
'root/static/images'
]);
valid_orientation
Returns an Hash reference of known orientations.
$tool->{valid_icon_sizes}->{'landscape'}; # valid
$tool->{valid_icon_sizes}->{'introverted'}; # invalid
AUTHOR
LNATION, <email at lnation.org>
BUGS
Please report any bugs or feature requests to bug-progressive-web-application at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Progressive-Web-Application. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Progressive::Web::Application
You can also look for information at:
RT: CPAN's request tracker (report bugs here)
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Progressive-Web-Application
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
ACKNOWLEDGEMENTS
LICENSE AND COPYRIGHT
Copyright 2019 LNATION.
This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a copy of the full license at:
http://www.perlfoundation.org/artistic_license_2_0
Any use, modification, and distribution of the Standard or Modified Versions is governed by this Artistic License. By using, modifying or distributing the Package, you accept this license. Do not use, modify, or distribute the Package, if you do not accept this license.
If your Modified Version has been derived from a Modified Version made by someone other than you, you are nevertheless required to ensure that your Modified Version complies with the requirements of this license.
This license does not grant you the right to use any trademark, service mark, tradename, or logo of the Copyright Holder.
This license includes the non-exclusive, worldwide, free-of-charge patent license to make, have made, use, offer to sell, sell, import and otherwise transfer the Package with respect to any patent claims licensable by the Copyright Holder that are necessarily infringed by the Package. If you institute patent litigation (including a cross-claim or counterclaim) against any party alleging that the Package constitutes direct or contributory patent infringement, then this Artistic License to you shall terminate on the date that such litigation is filed.
Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.