20200116のHTMLに関する記事は5件です。

Swipe.js スライド時にイベントを発火させる

Swipe.jsでiphoneライクなTimepickerを実装したので共有します。
出来上がりイメージ図はスクリーンショット 2020-01-16 19.50.25.png
こんな感じです。
コードはこちらから確認できます。
Timepicker using Swiper.js

公式ドキュメントはあまり参考ならなかったです。(わたし的に)
Swiper

補足

iphoneライクに指でスワイプできるようにすると
どうしてもイベントが発火しなかったので、
泣く泣く指スワイプは外しました。
(実装に成功した方は是非教えていただきたい)

ちなみに指スワイプを実装したコードは以下になります。

index.js
var defaults = {
  pagination: '.swiper-pagination',
  slidesPerView: 3,
  freeMode: true,
  freeModeSticky: true,
  freeModeMomentumRatio: 0.25,
  freeModeVelocityRatio: 0.25,
  freeModeMinimumVelocity: 0.1,
  mousewheelControl: true, <-- こいつと、
  mousewheelSensitivity: 0.5,  <-- こいつを実装する。
  loop: true,
  loopAdditionalSlides: 5,
  direction: 'vertical',
  slideToClickedSlide: true,
  centeredSlides: true
};

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PHPでシンプルなToDoアプリ(掲示板)を作る

データベース不要のToDoアプリを作る

はじめに

今回、シンプルなToDoアプリ(掲示板)を作りました。
言語はPHPのみで、MySQLなどのデータベースは一切使いません。
ToDoアプリ

今回作ったToDoアプリの特徴

  • 投稿内容はボタンで削除することができます。
  • 送信したときに画面遷移しません。

この記事の対象者

PHPの基礎を勉強している人,PHPやサーバーサイド言語に興味がある人などなど。

さっそく作きましょう!

わからない部分は一つ一つ調べ、進めていきましょう。

PHP(32行),HTML

スクリプトを3分割していますが、実際は全て一つのファイルに繋げて記述します。まずはPHP前半です。(主に変数の準備)

todo.php
<?php

//HTMLタグにお入力を無効にし、文字コードをutf-8にする
//(PHPのおまじないのようなもの)
function h($v){
    return htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
}

//変数の準備
$FILE = 'todo.txt'; //保存ファイル名

$id = uniqid(); //ユニークなIDを自動生成

//タイムゾーン設定
date_default_timezone_set('Japan');
$date = date('Y年m月d日H時i分'); //日時(年/月/日/ 時:分)

$text = ''; //入力テキスト

$DATA = []; //一回分の投稿の情報を入れる

$BOARD = []; //全ての投稿の情報を入れる

//$FILEというファイルが存在しているとき
if(file_exists($FILE)) {
    //ファイルを読み込む
    $BOARD = json_decode(file_get_contents($FILE));
}

☞ 今回の変数を保存する配列について

  • \$BOARD[] 全体の配列
  • \$DATA[\$id, \$date, \$text] 一回分の投稿(これを\$BOARD[]へ挿入していく)

結局、下記のような形で保存されます。
\$BOARD[\$DATA[\$id, \$date, \$text], \$DATA[省略], \$DATA[省略],...]

☞ 保存データの読み取り

詳細は後々説明しますが、今はなんとなくデータを持ってきて、変数に保存したんだなと思っておいてください。(最初の時点ではファイルもデータもないのでスルーでOK!
また、今回は全てのデータをJSON形式(今回はただの配列だと思ってください)で、todo.txtというファイルに保存していきます。

  • file_get_contents() ファイルを読み込む
  • json_decode() JSON形式をPHPで扱える形式に変換する

ここからのPHP後半が、ファイルを生成し、フォーム内容を保存していく手順になります。

todo.php
//$_SERVERは送信されたサーバーの情報を得る
//REQUEST_METHODはフォームからのリクエストのメソッドがPOSTかGETか判断する
if($_SERVER['REQUEST_METHOD'] === 'POST'){
    //$_POSTはHTTPリクエストで渡された値を取得する
    //リクエストパラメーターが空でなければ
    if(!empty($_POST['txt'])){
        //投稿ボタンが押された場合

        //$textに送信されたテキストを代入
        $text = $_POST['txt'];

        //新規データ
        $DATA = [$id, $date, $text];
        //新規データを全体配列に代入する
        $BOARD[] = $DATA;

        //全体配列をファイルに保存する
        file_put_contents($FILE, json_encode($BOARD));

    }else if(isset($_POST['del'])){
        //削除ボタンが押された場合

        //新しい全体配列を作る
        $NEWBOARD = [];

        //削除ボタンが押されるとき、すでに$BOARDは存在している
        foreach($BOARD as $DATA){
            //$_POST['del']には各々のidが入っている
            //保存しようとしている$DATA[0]が送信されてきたidと等しくないときだけ配列に入れる
            if($DATA[0] !== $_POST['del']){
                $NEWBOARD[] = $DATA;
            }
        }
        //全体配列をファイルに保存する
        file_put_contents($FILE, json_encode($NEWBOARD));
    }

    //header()で指定したページにリダイレクト
    //今回は今と同じ場所にリダイレクト(つまりWebページを更新)
    header('Location: '.$_SERVER['SCRIPT_NAME']);
    //プログラム終了
    exit;
}
?>

☞ 保存場所を作る

  • json_encode() メッセージの配列をJSON形式に変換する
  • file_put_contents(a,b) bの内容をファイルaに保存する(もしファイルaが存在しなければ自動で生成)

☞ 保存場所

今回は、最初にテキストが送信されたとき、投稿した情報である\$DATA(idと日時、入力文字)を、file_put_contents()を用いて自動生成したtodo.txtというファイルに保存します。

ToDoApp
├── todo.php
├── todo.txt(自動で生成される)

ここからがPHPの後に記述していくHTMLです

todo.php
<!DOCTYPE html>
<html lang= "ja">
<head>
    <meta name= "viewport" content= "width=device-width, initial-scale= 1.0">
    <meta http-equiv= "content-type" charset= "utf-8">
    <title>ToDoApp</title>
</head>
<body>
    <h1>ToDoアプリ</h1>

    <section class= "main">
        <h2>ToDoAppに投稿する</h2>

        <!--投稿-->
        <form method= "post">
            <input type= "text" name= "txt">
            <input type= "submit" value= "投稿">
        </form>    

        <table style= "border-collapse: collapse">
        <!--tableの中でtr部分をループ-->
        <?php foreach((array)$BOARD as $DATA): ?>
        <tr>
        <form method= "post">
            <td>
                <!--テキスト-->
                <?php echo h($DATA[2]); ?>
            </td>
            <td>
                <!--日時-->
                <?php echo $DATA[1]; ?>
            </td>
            <td>
                <!--削除-->
         <!--この時その投稿のidがサーバーに送信される-->
                <input type= "hidden" name= "del" value= "<?php echo $DATA[0]; ?>">
                <input type= "submit" value= "削除">
            </td>
        </form>
        </tr>
        <?php endforeach; ?>
        </table>
    </section>

☞ 今回のformについて

今回はフォームから入力した内容をPOST送信でサーバーに送信します。

☞ 投稿

テキストを入力し投稿ボタンを押したとき、そのテキスト内容がサーバーに送信されます。それと同時にPHPで\$idと\$dateを呼び出し\$textとともに\$DATAに格納します。この\$DATAを全体配列\$BOARD挿入し、保存します。

☞ 削除

削除ボタンを押したとき、その投稿のidがサーバーに送信されます。そのidが、すでに保存されている投稿のidと同じであれば保存せず、それ以外を保存しなおします。

CSS,JavaScript

CSSやJavaScriptを使うと、よりUIを整えることができます。

おわりに

今回はデータベースを使わずに、シンプルなToDoリストを作ってみました。もちろんデータが膨大になったり、複雑になったときはMySQLやFirebaseを使うといいでしょう。データが軽量かつシンプルに完結できる方法を模索した結果、このようなアプリを作ることができました。
何かアドバイス等あれば教えていただければと思います。
そして、この記事が皆様にお役に立てれば幸いです。

参考サイト

https://code-notes.com/lesson/4 ユニークなidを用いてデータを削除
確かな力が身につくPHP「超」入門 p.159 ファイル入出力

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Google しごと検索に求人情報が掲載されるようになるまで(勤務先住所が複数の場合)

Google for Jobs?
Google しごと検索??
Google 求人検索???

いま主流の呼び名ってどれなんでしょうね・・・
とにかく、Googleの検索結果に求人情報が出るようになったという例のアレです。

Google Japan Blog: Google しごと検索で、仕事探しをもっとスムーズに!
(2019年1月23日水曜日)

本日より、Google しごと検索 の提供を開始します。この新機能は、ウェブ上の転職・求人情報サイトや企業の採用ページ等から求人情報を探して、検索結果に分かりやすく表示します。

検索結果上に求人情報が表示されるようにした際のメモです。

主な参考記事

求人情報 | 検索 | Google Developers
構造化データに関するガイドラインに準拠する | 検索 | Google Developers

マークアップからINDEXまでの手順

  1. schema.orgの構造化データをマークアップする
    (フォーマット:JSON-LD, タイプ:JobPosting)
    構造化データタイプの定義 | 検索 | Google Developers

  2. チェックツールで重要なエラーがないかチェックする
    構造化データ テストツール

    • あくまでも構文チェックです。ガイドラインに準拠しているかまではチェックできないので、構文に問題が検出されなくても結果に表示されないことがあります。
    • 入力推奨プロパティは項目ごと削除すると警告が消える場合もあります。
  3. 書いた構造化データを対象ページの<body>タグ内に貼り付ける

  4. Google Search Consoleで対象ページのクロールリクエストを送る

    • これがライブテストだと上手くいかなかった・・・やり方が悪かったのかもしれません・・・)
  5. クロールの結果を確認する。
    (クロール完了まで時間がかかります)
    メニュー: 拡張 > 求人情報

  6. Googleで「〇〇(事業名) 求人」などのキーワードで検索し、求人検索結果に情報が表示されるようになったか検証する。

  7. 掲載された翌日以降、Google Search Consoleで表示回数があるかチェックする。
    メニュー: 拡張 > 求人情報 > 表示回数(チェックボックス)

  8. (※検索結果に求人が出てこない、表示回数が極端に少ない場合)
    構造化データにガイドライン違反などSEO的な問題がないかチェックする。

求人説明文のSEO

求人情報の説明文(description)に含まれているワードはGoogleの検索対象となっています。
説明文は、応募先ページの内容とマッチしている必要があります。
(マッチしていないとガイドライン違反になる可能性が高いです)
タグを入れなくても改行されるようなので、文章の見た目は試してみた方が早いです。
Search Consoleのライブテストで検証を行うと、Google上のページへの修正反映が早いです。

絞り込みへの対応

sample_01.png

「地域」への対応

掲載したい求人が訪問事業(=勤務先住所が変動する)だったので、jobLocationを配列にし、本部所在地の他、1つの構造化データで複数のエリアに対応しました。
住所を番地まで入れている本部所在地は、ページ上にマップと現在地からの経路が示されています。
(ただし、streetAddressを入れていないエリアで警告は出ています。。この影響でSearch Console表示回数が取れなくなっているかも。要検証。)

 "jobLocation": [
    {
      "@type": "Place",
      "address": {
        "@type": "PostalAddress",
        "streetAddress": "神田神保町1丁目14-1",
        "addressLocality": "千代田区",
        "addressRegion": "東京都",
        "postalCode": "101-0051",
        "addressCountry": "JP"
      }
    },
    {
      "@type": "Place",
      "address": {
        "@type": "PostalAddress",
        "streetAddress": "",
        "addressLocality": "中央区",
        "addressRegion": "東京都",
        "postalCode": "103-0000",
        "addressCountry": "JP"
      }
    },
    {
      "@type": "Place",
      "address": {
        "@type": "PostalAddress",
        "streetAddress": "",
        "addressLocality": "港区",
        "addressRegion": "東京都",
        "postalCode": "105-0000",
        "addressCountry": "JP"
      }
    },
  }
]

「投稿日」への対応

新しい投稿が上位に表示されているようです。
投稿日は構造化データのプロパティで更新することができます。

  "datePosted": "2020-01-01",
  "validThrough": "2039-01-01",

「形態」への対応

正社員とパートタイムの両方で設定したかったんだけど、2件合わせての設定は無理かも・・・
できたとしても、配列の構造の都合で給与額が「正社員は月給○○万」「パートタイムは時給○○円」という記述が恐らくできないです。
雇用形態ごとに別ページで管理するか、採用強化したい時期に合わせてプロパティを更新するのが良さそうです。

  "employmentType": "FULL_TIME",

「カテゴリ」「企業」への対応

入れても入れなくても反映される時があるようです・・・検証しきれていません。

引き続き検証の余地あり

わたしが現状で分かっていることはここまでです。
知見が増えたら更新します!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Vue.js] ケバブケースとかキャメルケースとかパスカルケースとか

Vueでのケースの書き方って場所によって何がいいか若干悩みますよね。(私だけ?)
なので、まとめてみました。

そもそも○○○ケースって?(復習)

一言で言うと「クラス名や変数名等の名前の付け方の総称」
覚えておくべきケースをざっと説明すると。。

ケバブケース

文字と文字の区切りを-で表現するやり方。「チェインケース」とも言う。
ケバブのお肉をぶっさしている感じからきているとか。:meat_on_bone:

this-case-is-god

キャメルケース

文字と文字の区切りを大文字で表現するやり方。
よく見るやつです。ラクダのこぶですね。:camel:

thisCaseIsGod

パスカルケース

文字と文字の区切りを大文字で表現+先頭の文字も大文字にする。
それもそのはず、「アッパーキャメルケース」とも呼ばれるのだから。
これもよく見ますね。

ThisCaseIsGod

どこにどのケースを書くべきか?

基本的に下記の方針でOK

  • コンポーネントは「パスカルケース」
  • JavaScriptでは「キャメルケース」
  • HTMLでは「ケバブケース」

記述に迷う主な例を挙げたいと思います。

コンポーネントは「パスカルケース」

<template>
  <MyComponent></MyComponent>
</template>

因みに、componentsに指定する際にパスカルケースであれば、ケバブケースでも記述できるが
ケバブケースで指定するとケバブケースでしか動かない。

<template>
  <MyComponent></MyComponent>     <!-- OK -->
  <my-component></my-component>   <!-- OK -->
  <MyComponent2></MyComponent2>   <!-- NG -->
  <my-component2></my-component2> <!-- OK -->
</template>

<script>
export default {
  components: {
    MyComponent,
    'my-component2': MyComponent2,
  }
}
</script>

props 属性は「ケバブケース」 その他は「キャメルケース」

<template>
  <MyComponent :my-data="hoge"></MyComponent>
</template>

<script>
export default {
  props: ['myData'],
}
</script>

emitは「ケバブケース」

JavaScript内だが文字列として定義しているだけで、
カスタムイベント名として使われるためケバブケース推奨

<script>
export default {
  methods: {
    hogeFunc() {
      this.$emit('my-emit')
    }
  }
}
</script>

最後に

書き終わった後に気づいたのですが、とても分かりやすい記事がありました。
参考にさせていただきます。
https://qiita.com/ngron/items/ab2a17ae483c95a2f15e

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

S3に静的HTMLファイルやSPAのスクリプトを配置して公開する

S3はファイルを補完するだけでなく、以下の手順を踏むことでHTTPサーバとしても利用することができます。
EC2などのサーバを立てなくても簡単にHTMLページが公開できます。
また、ReactやVueなどで作ったスクリプトを配置することもできます。費用はファイルサイズやアクセス数をベースに計算され、安価で簡単に情報公開ができるのでおすすめです。

S3バケットの作成

バケットを作成していない場合は、Create bucketボタンを押して、S3バケットを作ります。

最初のBucket nameは同じ名前のバケット名を(同じリージョンで)ほかの人が使っているとエラーが出ます。
重複しないバケット名を入れて、Nextを押して次に行きます。②~④は、一旦そのままの設定で構いません

Public access ブロックの解除

次に、Public access Blockの解除を行います。
前の手順で作成したバケットのチェックボックスをチェックした状態でEdit public settingsボタンを押します。
image.png

Block all public accessのチェックボックスを外し、Nextを押します。

すると、以下の様にPublic accessを許可してもよいかを確認する画面が出ます。ウインドウ下の入力欄に”confirm”と入力し、Confirmボタンを押します。

私はこの手順を踏むことでデータが公開された!と思ってしまいましたが、この段階ではPublic access blockを外しただけで公開設定をいれたわけではないので、公開はされていません。
次にBucketポリシーを変更して公開設定を行います。

Bucketポリシーの設定

次に、対象のバケット名をクリックし、バケットの中身の一覧画面に移動し、上に表示されるPermission>BucketPolicyの順にタブをクリックします。
タブの下にBucketPolicyEditorが表示されますので、以下に示したBucket policyを設定します。
example-bucketとなっている部分については、作成したバケット名に変更してください。

"bucketpolicy"
{
  "Version":"2012-10-17",
  "Statement":[{
    "Sid":"PublicReadGetObject",
        "Effect":"Allow",
      "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::example-bucket/*"
      ]
    }
  ]
}

Static website hosting の設定

最後に、Propertiesタブ>Static website hostingをクリックし, index document欄に初期ページとして表示するファイル名を設定します。ファイル名の指定なしにルートディレクトリを参照するURLを表示しようとした場合、ここで設定したファイルが自動的に読み込まれるようになります。
また、Error documentを設定すると、存在しないページなどを表示しようとした場合にここで指定したページが表示されるようになります。
image.png

これで設定完了です!
タイトルのすぐ下に表示されているEndpointのURLをクリックすると、S3のルートディレクトリに登録されているindex.htmlを参照できます。

参考ページ
https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteAccessPermissionsReqd.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む