スタッフブログ Staff Blog

初心者向けプログラミング学習アプリ「Progate」

初心者向けのプログラミング学習アプリ「Progate」。

SNSで見かけて気になったので使ってみました。

まだHTML & CSS初級編の2レッスンしかやっていませんが、ゲーム感覚で勉強できて、解説もわかりやすいです。

私はこれまで本等で何度か勉強しようとして、なんとなく知識だけは持っているものの、いざ実践!となるとできない状態だったので、実際にやりながら(最初はカンタンな穴埋めから)学べるのはとても良いです。

正解するまで先に進めないのですが、すぐにヒントも見ることができるのでストレスもたまりにくい気がします。

まだほんの初歩段階だからかもしれませんが^^;

スマホアプリなので空き時間ができた時などにすぐ使えるのも良いです。

私はデザインまでしか担当していないのですが(社内に優秀なエンジニアが3人いるので出番もないのですが)、プログラミングのことも知っておくとお客様との話もスムーズですし、プロジェクトが効率的に進みますよね。

と思ってこれまで何度かチャレンジしては挫折してきたので・・・気長にやってみようと思います。

年々勉強は苦痛なものになってきているので、「楽しい」と感じながら学べるのはすごく大事だな、と思いました。

無料から始められるので敷居も低いですね。

UI開発者の夏休み

顧客企業様のご理解・ご協力も賜りまして、今年は土・日も含め6日間の夏季休暇を頂きました。普段仕事をしていると勤務時間以外にもつい考え事をしたり、「こんなコードにすると上手くいくかな?」などと実験をしたりしがちなので、休みの間は仕事のことを忘れリフレッシュの時間に充てました。

8月15日には「福山夏まつり あしだ川花火大会」へと出かけました。写真を撮ることが趣味ですので一眼レフカメラに三脚を携え、2回目のあしだ川花火大会の撮影にチャレンジしたのです。今年は開始直前に雨が降り少々大変でしたが、昨年よりも見栄えの良い写真を撮ることができたように思います。

「黒いうちわ」で多重露光をしてみようと考えていたのですが雨降りで操作が大変でしたので、ソフトウェアで擬似的な多重露光の作品に仕上げてみました。カラフルな花火の美しさをお届けできたら、と思います。
写真:あしだ川花火大会で打ち上げられたカラフルな花火

撮影した写真はInstagramなどのSNSでもシェアしています。福山をはじめ私が訪ねた土地の美しい風景を少しでも多くの人に届け、仕事以外でも地元に貢献できたらなと考えているこの頃です。

仕事を離れ一市民としてWebを閲覧してみて気付く点もありました。

  • マッサージの空き状況を確認しながら予約できるのは便利だな
  • 今日の天候で花火大会が開催されるか知りたいけれど、サイトが混雑してつながらないな
  • 道の駅の公式Webページを見たいのだけれど、検索しても結果に出てこないような気がする
  • 腱鞘炎のような症状があるので診察をしてもらいたいのだけれど、いつまでお盆の休診なのだろう
  • ページの内容を早く見たいのだけれど、毎回アニメーションがあり見えるまでに時間がかかるな

こうした経験はこれからの業務にも役立てていけたらなと感じました。

2018年も2/3が過ぎようとしています。休暇で蓄えたパワーを基に、残りの1/3の日々も頑張っていきたいと思います。

スマホと一眼カメラの写真比較(食べ物編)

LABでは、Webサイトを作る際に使用する画像の撮影も併せてご依頼いただくことが多いのですが

「普段iPhoneで撮ってるんですが使えますか?」

「スマホで撮るのとどのくらい違うのですか?」

と聞かれることがあります。


そこで、iPhoneXとミラーレス一眼カメラ(SONY α7R III)で比較してみました。

照明等は特に使用せず、AFでピントを合わせてシャッターを押しただけのものです。
スマホとカメラで画角が違うので、ほぼ同じ大きさになるよう周りをカットしています。

iPhoneX


ミラーレス一眼


iPhoneX


ミラーレス一眼


iPhoneX


ミラーレス一眼

どちらもシャッターを押しただけですが、

デジタル一眼カメラの方が明るく、ピントを合わせたい場所に合わせられ、背景を綺麗にぼかすことができます。

実際に目で見たときよりもキレイな気もしますが、実物には「感動」も加わるため、写真ではこのくらいでちょうど良いのかもしれません。

そして雰囲気や質感は一眼の方が近いように感じます。

スマートフォンで撮影したものでもPhotoshopで加工すれば、元よりキレイに見せることはできますが、一眼にはやはり敵わず、加工コストもかかりますので、可能であれば一眼での撮影をおすすめします。

Google Analytics APIでサイト内のアクセスランキングを実装(2)

前回Google Analytics APIでサイト内のアクセスランキングを実装する方法をご紹介しましたが、その実装を発展させてCMSと連携する方法をご紹介します。

前回の方法では、ランキングのタイトルやリンク先などをGoogle Analyticsのカスタムディメンションに保存していましたが、その方法ではページの公開後にタイトルやURLなどを変更すると別ページのアクセスとしてカウントされたランキングとなる問題がありました(APIのdata_ga->get()メソッドで複数のカスタムディメンションを指定した際にand検索となっているため)。

今回の実装方法ではその問題を解消し、さらにより多くの情報を取得可能になります。

CMSと連携する仕組み

今回のCMSと連携する方法では、CMSでページを生成した際にCMSが持つページ固有のIDをカスタムディメンションに保存します。
そうすることでカスタムディメンションにタイトルなどの情報を保存する必要がなく、タイトルなどの情報を取り出す際はそのIDを利用してPHPから動的にCMSに保存した情報を取り出すことで実現します。

ページIDはユニークな値であり、作成後に変更されることがありませんのでページ公開後にタイトルを変更した場合でもランキングに影響が出ず、さらに最新のタイトルを反映することが可能になります。

Movable Typeの記事から情報を取得する

今回はMovable Typeの記事として作成したページの情報を取り出す方法をご紹介します。
引数の「$entry_id」はカスタムディメンションに保存したIDを取り出して渡します。

以下のサンプルではMovable Typeの記事からタイトル、公開ステータス、公開日時、パーマリンクを取得しています。

function getEntryObject($entry_id) {
  $mt_dir = '/powercms/app/sites/01/mt/';
  require_once($mt_dir . 'php/mt.php');

  $blog_id = 1;
  $mt = MT::get_instance($blog_id, $mt_dir. 'mt-config.cgi');
  $entry = $mt->db()->fetch_entry($entry_id);
  $permalink = $mt->db()->entry_link($entry_id, 'Individual');

  $entry_obj_value = array();
  if (isset($entry->status) && isset($entry->title) && isset($entry->created_on) && isset($permalink)) {
    $status = $entry->status;
    $title = $entry->title;
    $date = new DateTime($entry->created_on);
    $date = $date->format('y-m-d');
    $url = $permalink;

    $entry_obj_value['status'] = $status;
    $entry_obj_value['title'] = $title;
    $entry_obj_value['date'] = $date;
    $entry_obj_value['url'] = $url;
  }
  return $entry_obj_value;
}

カスタムフィールドの情報を取り出す

カスタムフィールドの情報を取り出す場合は$entry->{'entry_field.カスタムフィールドのベースネーム'}で取り出すことが可能です。

function getEntryObject($entry_id) {
  $mt_dir = '/path/to/mt/';
  require_once($mt_dir . 'php/mt.php');

  $blog_id = 1;
  $mt = MT::get_instance($blog_id, $mt_dir. 'mt-config.cgi');
  $entry = $mt->db()->fetch_entry($entry_id);

  if (isset($entry->{'entry_field.カスタムフィールドのベースネーム'})) {
    $sub_title = $entry->{'entry_field.カスタムフィールドのベースネーム'};
  }
}

Movable Typeの記事から情報を取得してランキングのJSONを返すPHPの実装

では、前回の実装と組み合わせて、Movable Typeの記事から情報を取得してランキングのJSONを返すPHPを実装します。 尚、Movable Typeから記事の情報を動的に取得するように変更したことで記事ステータスが公開中のもののみ表示することが可能です。

これによりランキング入りしたページが削除や非公開となった場合にランキングに表示しない(表示が残る場合はリンク切れとなります)ことが出来ます。

header("Content-Type: application/json; charset=UTF-8");

// ライブラリのパス
require_once 'vendor/autoload.php';
// サービスアカウントを作成した際に取得したJSONのパス
define('KEY_FILE_LOCATION', 'json/auth.json');
// Google AnalyticsのビューID
define('VIEW_ID', 'xxxxxxxxx');

$analytics = initAnalytics();
getPageviewsRanking($analytics, VIEW_ID);

function initAnalytics() {
  $client = new Google_Client();
  $client->setApplicationName('Analytics Reporting');
  $client->setAuthConfig(KEY_FILE_LOCATION);
  $client->setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
  $analytics = new Google_Service_Analytics($client);
  return $analytics;
}

function getPageviewsRanking($analytics) {
  $json = array(
    'status' => '',
    'message' => '',
    'data' => array()
  );
  $start = isset($_GET['start']) ? htmlspecialchars($_GET['start'], ENT_QUOTES) : '';
  $end = isset($_GET['end']) ? htmlspecialchars($_GET['end'], ENT_QUOTES) : '';
  $is_error = false;
  $error_message = '';

  if (empty($start) || empty($end)) {
    $is_error = true;
    $error_message = 'パラメータが指定されていません。start/endを指定してください。';
  } else if (!strptime($start, '%Y-%m-%d') || !strptime($end, '%Y-%m-%d')) {
    $is_error = true;
    $error_message = 'パラメータの指定が正しくありません。start/endをYYYY-mm-ddの形式で指定してください。';
  }

  if (!$is_error) {
    $results = $analytics->data_ga->get(
      'ga:' . VIEW_ID,
      $start,
      $end,
      'ga:pageviews',
      array(
        'dimensions' => urlencode('ga:dimension1,ga:dimension2'),
        'sort' => urlencode('-ga:pageviews'),
        'max-results' => '10'
      )
    );

    if (count($results->getRows()) > 0) {
      $rows = $results->getRows();
      foreach ($rows as $row) {
        $id = isset($row[1]) ? $row[1] : '';
        $pv = isset($row[2]) ? $row[2] : '';
        $entry_obj_value = getEntryObject($id);
        if (isset($entry_obj_value['status']) && $entry_obj_value['status'] === '2') {
          $entry = array(
            'status' => $entry_obj_value['status'],
            'id' => $id,
            'title' => $entry_obj_value['title'],
            'url' => $entry_obj_value['url'],
            'date' => $entry_obj_value['date'],
            'pv' => $pv
          );
          $json['data'][] = $entry;
          if (count($json['data']) === 10) {
            break;
          }
        }
      }
      if (isset($json['data']) && count($json['data']) > 0) {
        $json['status'] = 'success';
        echo json_encode($json);
      } else {
        $is_error = true;
        $error_message = '指定期間内のランキングがありません。';
      }
    } else {
      $is_error = true;
      $error_message = '指定期間内のランキングがありません。';
    }
  }

  if ($is_error) {
    $json['status'] = 'error';
    $json['message'] = $error_message;
    die(json_encode($json));
  }
}

function getEntryObject($entry_id) {
  $mt_dir = '/powercms/app/sites/01/mt/';
  require_once($mt_dir . 'php/mt.php');

  $blog_id = 1;
  $mt = MT::get_instance($blog_id, $mt_dir. 'mt-config.cgi');
  $entry = $mt->db()->fetch_entry($entry_id);
  $permalink = $mt->db()->entry_link($entry_id, 'Individual');

  $entry_obj_value = array();
  if (isset($entry->status) && isset($entry->title) && isset($entry->created_on) && isset($permalink)) {
    $status = $entry->status;
    $title = $entry->title;
    $date = new DateTime($entry->created_on);
    $date = $date->format('y-m-d');
    $url = $permalink;

    $entry_obj_value['status'] = $status;
    $entry_obj_value['title'] = $title;
    $entry_obj_value['date'] = $date;
    $entry_obj_value['url'] = $url;
  }
  return $entry_obj_value;
}

まとめ

今回はMovable Typeの記事の情報を取り出す方法をご紹介しましたが、DBから情報を取得する手段があれば他CMSにも応用可能です。

また、ランキングに記事のサムネイルや概要文を表示する場合など、より多くの情報を取り出すことが出来ますのでCMSを利用している場合には前回ご紹介した方法よりも良いと言えるでしょう。

Google Analytics APIでサイト内のアクセスランキングを実装(1)

Google Analyticsを導入しているサイトで、Google Analyticsのデータを利用してサイト内のアクセスランキングを実装する方法をご紹介します。

ランキングを取得するための事前準備

Google API Consoleでの設定

  • Google API Consoleでプロジェクトを作成します
  • API ライブラリからAnalytics APIを探して有効にします。
  • 認証情報からサービスアカウントを作成してJSONを取得します。
  • サービスアカウントを作成すると自動的にメールアドレスが作成されます。

Google Analyticsでの設定

  • ランキングを取得するビューのユーザー管理者に上記で作成したサービスアカウントのメールアドレスを追加します。
  • 後述する特定のページを対象としたランキングにしたい場合はカスタム定義からカスタムディメンションを作成しておきます。

PHPライブラリのインストール

Composerでインストールするか

{
  "require": {
    "google/apiclient": "2.*"
  }
}

google/google-api-php-clientからダウンロードして設置します。

アクセス順にランキングを取得する

今回は以下の実装でアクセス順のランキングを取得します。

ランキングのJSONを返すPHPの実装

期間を指定してアクセス順のランキングをJSONで返すPHPコードを実装します。
以下のPHPを「start」と「end」パラメータで期間を指定して実行すると、指定期間のランキングJSONを取得します。

例) 直近1週間のランキングを取得する場合
example.php/?start=2018-07-23&end=2018-07-30

header("Content-Type: application/json; charset=UTF-8");

// ライブラリのパス
require_once 'vendor/autoload.php';
// サービスアカウントを作成した際に取得したJSONのパス
define('KEY_FILE_LOCATION', 'json/auth.json');
// Google AnalyticsのビューID
define('VIEW_ID', 'xxxxxxxxx');

$analytics = initAnalytics();
getPageviewsRanking($analytics, VIEW_ID);

function initAnalytics() {
  $client = new Google_Client();
  $client->setApplicationName('Analytics Reporting');
  $client->setAuthConfig(KEY_FILE_LOCATION);
  $client->setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
  $analytics = new Google_Service_Analytics($client);
  return $analytics;
}

function getPageviewsRanking($analytics) {
  $json = array(
    'status' => '',
    'message' => '',
    'data' => array()
  );
  $start = isset($_GET['start']) ? htmlspecialchars($_GET['start'], ENT_QUOTES) : '';
  $end = isset($_GET['end']) ? htmlspecialchars($_GET['end'], ENT_QUOTES) : '';
  $is_error = false;
  $error_message = '';

  if (empty($start) || empty($end)) {
    $is_error = true;
    $error_message = 'パラメータが指定されていません。start/endを指定してください。';
  } else if (!strptime($start, '%Y-%m-%d') || !strptime($end, '%Y-%m-%d')) {
    $is_error = true;
    $error_message = 'パラメータの指定が正しくありません。start/endをYYYY-mm-ddの形式で指定してください。';
  }

  if (!$is_error) {
    $results = $analytics->data_ga->get(
      'ga:' . VIEW_ID,
      $start,
      $end,
      'ga:pageviews',
      array(
        'dimensions' => urlencode('ga:dimension1,ga:dimension2,ga:dimension3'),
        'sort' => urlencode('-ga:pageviews'),
        'max-results' => '10'
      )
    );

    if (count($results->getRows()) > 0) {
      $rows = $results->getRows();
      foreach ($rows as $row) {
        $title = isset($row[1]) ? $row[1] : '';
        $url = isset($row[2]) ? $row[2] : '';
        $pv = isset($row[3]) ? $row[3] : '';

        if (isset($title)) {
          $entry = array(
            'title' => $title,
            'url' => $url,
            'pv' => $pv
          );
          $json['data'][] = $entry;
          if (count($json['data']) === 10) {
            break;
          }
        }
      }
      if (isset($json['data']) && count($json['data']) > 0) {
        $json['status'] = 'success';
        echo json_encode($json);
      } else {
        $is_error = true;
        $error_message = '指定期間内のランキングがありません。';
      }
    } else {
      $is_error = true;
      $error_message = '指定期間内のランキングがありません。';
    }
  }

  if ($is_error) {
    $json['status'] = 'error';
    $json['message'] = $error_message;
    die(json_encode($json));
  }
}

なお、サンプルコードでは以下のカスタムディメンションを持ったデータのみを対象に取得しています。

  • カスタムディメンション1: ランキング対象フラグ
  • カスタムディメンション2: ページタイトル
  • カスタムディメンション3: ページURL

事前にカスタムディメンションの作成とトラッキングコードの変更が必要です。

トラッキングコードの例

gtag.jsでは以下のようにコードを変更します。

const GA_TRACKING_ID = 'UA-123180440-1';
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', GA_TRACKING_ID, {
  'custom_map': {
    'dimension1': 'ranking_flag',
    'dimension2': 'page_title',
    'dimension3': 'page_url'
  },
  'ranking_flag': 'is_ranking',
  // ランキングのタイトルとしたい文字列を設定します
  'page_title': 'スタッフブログ',
  // ランキングのURL(リンク先)を設定します
  'page_url': '/blog/'
});

ランキングをページへ表示するJS

JSでランキングのJSONを取得してページへ表示します。以下のサンプルではjQueryMoment.jsを利用しています。

(function($) {
  $(function() {
    var startDate = moment().subtract(1, 'days').format('YYYY-MM-DD');
    var endDate = moment().subtract(8, 'days').format('YYYY-MM-DD');
    $.ajax({
      'type': 'GET',
      'url': 'example.php',
      'data': 'start=' + startDate + '&end=' + endDate
    }).done(function(json) {
      if (json.status === 'success' && json.data) {
        // 成功した場合
      } else if (json.status === 'error' && json.message) {
        // 失敗した場合
      }
    });
  });
}(jQuery));

まとめ

一般的なウェブサイトでは多く導入されているGoogle Analyticsのデータを利用することで、データベースへアクセスを記録してPHPで集計するような実装を行わなくてもサイト内のアクセスランキングを実装することが可能です。

今回はランキングの情報として表示する内容をカスタムディメンションに直接保存していますが、ページの公開後にタイトルが変更されると別ページ扱いとなります。

そういった問題への対策や、またタイトルやURL以外により多くの情報(例えばサムネイルやページの概要など)を取得したい場合はCMSと連携して動的に取得すると良いでしょう。次回はCMSと連携する方法をご紹介します。

お問い合わせ Contact

制作のご依頼、ご相談などは下記のフォームからご連絡ください。