地域活動にに対してデジタルを推進する動きが始まっています。

  • ホームページ
  • デジタル回覧板
  • メーリングリスト
みんなスマホを持っているのだから、紙の回覧板を回すのはちょっと面倒です
line公式アカウント、自治会アプリなどでデジタル化できますが、結構費用が掛かります
 
レンタルサーバは220円/月で利用できるところがあります
ここにホームページとWEBプッシュ対応デジタル回覧板を作ればいいです
ホームページはwordpressで作れば簡単
 
アプリはPHPで作り、少し汎用性を入れましたので、サーバにアップすればそのまま使えます
運用は、コンテンツのスクショをパソコンで撮って、サーバにアップするだけです。
アップロード専用のアプリも作りました
 
ちょっとしたプログラミングやIT知識でいろんなことの融通性が高まります
 
今回作ったWEBプッシュ対応デジタル回覧板は下記を使いました
  • pushcode
  • bootstrap5
  • jquery
  • fontawsome
  • javascript シングルページ対応のため、コーディング
売りはpushcodeに対応した通知ができることです。IPHONEにも対応しています
アプリと同じようにホーム画面にアイコンを置けます
5000件/月まで無料で使えるので、町内会では週1で配信ができます
シングルページにしたので、フッター部のアイコンをクリックすると動的にコンテンツを取得して、配置します
 
紙の町会だよりのコンテンツを画像化して登録します
できたソースは
<?PHP
 //デジタル回覧板システム
//外部サイトへのURL取得
$xml=simplexml_load_file("siteinfo.xml");
if ($xml===FALSE) {
    return;
}else {
    $homepage=$xml- > homepage;
    $mail=$xml- > mail;
}
?> 
< !DOCTYPE html > &lthtml lang="ja" > &lthead > &ltmeta charset="UTF-8"/ > &ltmeta name="viewport"content="width=device-width, initial-scale=1" > &ltlink rel="manifest"href="/push/manifest.json" > &ltlink href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"rel="stylesheet"integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM"crossorigin="anonymous" > &ltscript defer src="https://www.pushcode.jp/dist/js/pushcode.js" > </script > &ltlink rel="stylesheet"href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" > &ltscript src="https://kit.fontawesome.com/25fb059f3e.js"crossorigin="anonymous" > </script > &ltscript src="https://code.jquery.com/jquery-3.7.1.min.js"integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="crossorigin="anonymous" > </script >
 &ltscript > window.PushCodeInit=function() {
    try {
        if (PushCode && PushCode.isSupport()) {
            PushCode.init( {
                    domainToken: 'dxxxxxxxxxxxxxxxxxxxxxxa',
                    userid: '',
                    serviceWorkerPath: '/push/pushcode_sw.js',
                    scopePath: '/push/'
                }

            );
            PushCode.components.openSubscribeDialog();
        }
    }

    catch (err) {
        console.error(err);

        if (PushCode) {
            PushCode.sendError(err);
        }
    }
}
;
</script > 
&lttitle > デジタル回覧板</title > &ltmeta name="msapplication-square70x70logo"content="/site-tile-70x70.png" > &ltmeta name="msapplication-square150x150logo"content="/site-tile-150x150.png" > &ltmeta name="msapplication-wide310x150logo"content="/site-tile-310x150.png" > &ltmeta name="msapplication-square310x310logo"content="/site-tile-310x310.png" > &ltmeta name="msapplication-TileColor"content="#0078d7" > &ltlink rel="shortcut icon"type="image/vnd.microsoft.icon"href="/push/images/favicon.ico" > &ltlink rel="icon"type="image/vnd.microsoft.icon"href="/push/images/favicon.ico" > &ltlink rel="apple-touch-icon"sizes="57x57"href="images/apple-touch-icon-57x57.png" > &ltlink rel="apple-touch-icon"sizes="60x60"href="images/apple-touch-icon-60x60.png" > &ltlink rel="apple-touch-icon"sizes="72x72"href="images/apple-touch-icon-72x72.png" > &ltlink rel="apple-touch-icon"sizes="76x76"href="images/apple-touch-icon-76x76.png" > &ltlink rel="apple-touch-icon"sizes="114x114"href="images/apple-touch-icon-114x114.png" > &ltlink rel="apple-touch-icon"sizes="120x120"href="images/apple-touch-icon-120x120.png" > &ltlink rel="apple-touch-icon"sizes="144x144"href="images/apple-touch-icon-144x144.png" > &ltlink rel="apple-touch-icon"sizes="152x152"href="images/apple-touch-icon-152x152.png" > &ltlink rel="apple-touch-icon"sizes="180x180"href="images/apple-touch-icon-180x180.png" > &ltlink rel="icon"type="image/png"sizes="36x36"href="images/android-chrome-36x36.png" > &ltlink rel="icon"type="image/png"sizes="48x48"href="images/android-chrome-48x48.png" > &ltlink rel="icon"type="image/png"sizes="72x72"href="images/android-chrome-72x72.png" > &ltlink rel="icon"type="image/png"sizes="96x96"href="images/android-chrome-96x96.png" > &ltlink rel="icon"type="image/png"sizes="128x128"href="images/android-chrome-128x128.png" > &ltlink rel="icon"type="image/png"sizes="144x144"href="images/android-chrome-144x144.png" > &ltlink rel="icon"type="image/png"sizes="152x152"href="images/android-chrome-152x152.png" > &ltlink rel="icon"type="image/png"sizes="192x192"href="images/android-chrome-192x192.png" > &ltlink rel="icon"type="image/png"sizes="256x256"href="images/android-chrome-256x256.png" > &ltlink rel="icon"type="image/png"sizes="384x384"href="images/android-chrome-384x384.png" > &ltlink rel="icon"type="image/png"sizes="512x512"href="images/android-chrome-512x512.png" > &ltlink rel="icon"type="image/png"sizes="36x36"href="images/icon-36x36.png" > &ltlink rel="icon"type="image/png"sizes="48x48"href="images/icon-48x48.png" > &ltlink rel="icon"type="image/png"sizes="72x72"href="images/icon-72x72.png" > &ltlink rel="icon"type="image/png"sizes="96x96"href="images/icon-96x96.png" > &ltlink rel="icon"type="image/png"sizes="128x128"href="images/icon-128x128.png" > &ltlink rel="icon"type="image/png"sizes="144x144"href="images/icon-144x144.png" > &ltlink rel="icon"type="image/png"sizes="152x152"href="images/icon-152x152.png" > &ltlink rel="icon"type="image/png"sizes="160x160"href="images/icon-160x160.png" > &ltlink rel="icon"type="image/png"sizes="192x192"href="images/icon-192x192.png" > &ltlink rel="icon"type="image/png"sizes="196x196"href="images/icon-196x196.png" > &ltlink rel="icon"type="image/png"sizes="256x256"href="images/icon-256x256.png" > &ltlink rel="icon"type="image/png"sizes="384x384"href="images/icon-384x384.png" > &ltlink rel="icon"type="image/png"sizes="512x512"href="images/icon-512x512.png" > &ltlink rel="icon"type="image/png"sizes="16x16"href="images/icon-16x16.png" > &ltlink rel="icon"type="image/png"sizes="24x24"href="images/icon-24x24.png" > &ltlink rel="icon"type="image/png"sizes="32x32"href="images/icon-32x32.png" > < !-- Webpush機能搭載 -- > &ltstyle > a {
    text-decoration: none;
    color: #fff;
}

.space100 {
    height: 400px;
}

.s16 {
    font-size: 10px;
}

.s20 {
    font-size: 16px;
}

</style > </head > &ltbody > &ltdiv class=container > &ltdiv class=row > &ltdiv class="col-12  bg-primary text-white" > &lth4 class="text-center" > 三ツ沢上町デジタル町会だより</h4 > </div > < !--動的にコンテンツが変わります-- > &ltdiv id=contents class="col-12" > &ltimg class=img-fluid src=contents/tayori.png alt="" > &ltimg class=img-fluid src=contents/tayori_2.png alt="" > </div > &ltdiv class=space100 > .</div > < !--fottermenu-- > &ltdiv class="d-block footer-menu-bar w-100 fixed-bottom bg-secondary text-white s16" > &ltdiv class="row m-2" > &ltp class="text-center s20" > 通知を許可するとスマホに最新情報のお知らせが届きます</p > &ltdiv id=link_home class="col text-center" > &lta href="<?PHP print $homepage;?>" > &lti class="fa-solid fa-house-chimney fa-2xl" > </i > </a > &ltbr > ホームページ </div > &ltdiv id=link_tayori class="col text-center" > &lti class="fa-solid fa-newspaper fa-2xl" > </i > &ltbr > 町会だより </div > &ltdiv id=link_news class="col text-center" > &lti class="fa-solid fa-newspaper fa-2xl" > </i > &ltbr > お知らせ </div > &ltdiv id=link_disaster class="col text-center" > &lti class="fa-solid fa-house-fire  fa-2xl" > </i > &ltbr > 防災 </div > &ltdiv id=link_event class="col text-center" > &lti class="fa-regular fa-calendar-days fa-2xl" > </i > &ltbr > イベント </div > &ltdiv id=link_trash class="col text-center" > &lti class="fa-solid fa-trash fa-2xl" > </i > &ltbr > ゴミ</i > </a > </div > &ltdiv id=link_mail class="col text-center" > &lta href="<?PHP print $mail;?>" > &lti class="fa-regular fa-envelope fa-2xl" > </i > &ltbr > 問い合わせ</a > </div > </div > </div > </div > </div > 
 
&ltscript >
//シングルページの部分、アイコンクリックでコンテンツを更新
 $("#link_tayori").on('click', function() {
        get_file("tayori.php");
    }
);
$("#link_news").on('click', function() {
        get_file("news.php");
    });
$("#link_disaster").on('click', function() {
        get_file("disaster.php");
    });
$("#link_event").on('click', function() {
        get_file("event.php");
    });
$("#link_trash").on('click', function() {
        get_file("trash.php");
    });
function get_file(w) {
    $.get(w,
        function(data) {
            $("#contents").html(data);
        }
    );
//クリックがわかるようにバイブレーション
    if(window.navigator.vibrate) {
        window.navigator.vibrate([100]);
    }

    else if(window.navigator.mozVibrate) {
        window.navigator.mozVibrate([100]);
    }

    else if(window.navigator.webkitVibrate) {
        window.navigator.webkitVibrate([100]);
    }    else {
        alert("sorry (T-T)");
    }
}
</script > </body > </html >
運用
 コンテンツに連番を付けてサーバにアップするだけ
 アップロード用のページも別途作りました
 
 
アップロード
<html>
<head>
<title>画像をドラッグ&ドロップで一括アップロード</title>
<script src="../js/dropzone.js"></script>
<link rel="stylesheet" href="../css/dropzone.css?v=1473248119" />
<link rel="stylesheet" href="../css/style.css?v=1473248119" />


</head>
<body>
<pre>
contents画像コンテンツを連番で作成しアップロードします

tayori.php		tayori_??.png
news.php		news_??.png

</pre>
<form action="upload.php"
      class="dropzone"
      id="my-awesome-dropzone">
</form>
<form action=delall.php>
	<input type=submit value=コンテンツ削除>
<form>
</body>



</html>
ファイル設置
<?php
$ds          = DIRECTORY_SEPARATOR;  
$storeFolder = '../contents';  
if (!empty($_FILES)) {
        $tempFile = $_FILES['file']['tmp_name'];                
     $ext=substr($_FILES['file']['name'],-3,3);
        $targetFile =  $targetPath. $_FILES['file']['name']; 
   $a=(move_uploaded_file($tempFile,'../contents/'.$targetFile));
構成
contents                                                      画像コンテンツ
tayori.php                   tayori_??.png
news.php                    news_??.png
event.php                    event.png             スケジュール画像
siteinfo.xml                                  外部サイトURL(ホームページ、問い合わせ)
pushcode_sw.js                             pushcodeスクリプト
manifest.json                                PWA
images
           logo.png                             サイトロゴ
 index.php
           tayori.php                          町会だより
           news.php                           お知らせ
           event.php                           イベントスケジュール
           disaster.php                       防災
           trash.php                           ゴミ
           mail.php                            問い合わせ

コンテンツ

homepage                           外部へリンク

tayori.php                          町会だより             画像

<?php
$t="&ltimg class='img-fluid' src=contents/[file]>";
$d = dir("contents");
while (false !== ($entry = $d->read())) {
  if (false !== strpos($entry, 'tayori_')) {
    echo str_replace("[file]",$entry,$t);
 }
}
$d->close();

news.php                           お知らせ              画像

<?php
$t="&ltimg class='img-fluid' src=contents/[file]>";
$d = dir("contents");

while (false !== ($entry = $d->read())) {
 if (false !== strpos($entry, 'news_')) {
   echo str_replace("[file]",$entry,$t);
 }
}
$d->close();

event.php                           イベントスケジュール        固定画像

 <img class="img-fluid  d-block mx-auto" src=contents/event.png alt="">
<div class=space100>/</div>
disaster.php 防災                HTMLで作成 trash.php ゴミ                HTMLで作成 mail.php 問い合わせ             外部へリンク