「開発」カテゴリーアーカイブ

“examination_v2.js”を公開しました

“examination.js”(初版)の改良版である”examination_v2.js”の公開を開始しました!
ダウンロード固定ページ“より”テストキットv2″を選択してください。

“テストキット2″から”テストキットv2″に変更します(2020/12/06)

このjsファイルはWordPress用ではありません。

“examination_v2.js”の特徴は以下の通りです。

  • 一問一答が可能に(従来の全問表示形式との切替可)
  • 一問一答ではリストマーカー(リスト文頭の記号)の変更、誤答終了(誤答した時点で不合格)も利用可
  • 解答欄○×表示(文頭)
  • 正答が解答欄とは別表示に
  • 採点結果がアラートから問題文の下に

ページ下にある見本を試していただくと分かるのですが、一問一答はただ小問を次々と送っていくだけではなく、大問の表示切替にも対応しています。今回のセールス?ポイントはそこにあると思っていて、実装に時間がかかったのもその部分でした。

このように機能が増えた一方、jsファイルを埋め込むhtmlファイルは処理の関係から”HTML5であること”が必須となりました(初版はHTML 4.01以降であれば動作します)。またそれに加えて以下の条件が追加されています。満たさない項目が1つでもあると動作しない可能性がありますのでご注意ください。(配布ファイル内の”カスタマイズの手引.txt”にも同じ内容を記載しています)

  • 1つの解答欄(テキストボックスまたはセレクトボックス)を子要素に持つli要素1つ(以下、”解答欄を持つli要素”)を1問とすること
  • 解答欄を持つli要素はform要素の孫要素(form > olまたはul > li)とすること
  • 解答欄を持つli要素と解答欄がないli要素(問題文として表示)は別のolまたはul要素とすること(1つの要素内に混在してはならない)
  • 変数dispIdと同じ値(初期値は”examination”)をid属性の値とした要素はform要素の最後の子要素とすること

なお、初版の配布ファイル内の”sample.html”はこれらの条件をすべて満たしているので、要素の子孫関係が変わらない限りはjsファイルを入れ替えるだけで使用可能です。

最後に、”テストキット2″に同梱の”sample.html”の内容を見本として掲載します。”採点”ボタンを押すと次の問題が表示され、最終問題を採点すると結果が出ます。

数字や英字、記号はすべて半角小文字で、それ以外は全角文字で記入してください。(1問10点、合格は100点満点中80点以上)

1 : 入力方式

次の問いに答えなさい。

  1. 1+1=
  2. (98+76)/(543-21)x0=
  3. この問題の点数は1問
  4. 円周率π=15926535…
  5. “日本”は英語(5文字)で

2 : 選択方式

次の問いをよく読み、選択肢の中から正しい答えを選びなさい。

  1. アルファベットの最初の文字はである。
  2. 1000グラムは1である。
  3. 光の速さは音の速さ
  4. CO2とはの化学式である。
  5. 地球は系にある惑星の1つである。

WordPressで、カスタムフィールドのみを使って記事を投稿する(おまけ)

シリーズのおまけです。本編から3年くらい経ってますが…

実は、カスタムフィールドのみを使って記事を投稿することによって、意味を成さなくなる機能があります。それは、検索機能です。

search_keyword

上の画像はブログ”第一駅撮区”の検索結果を撮ったものですが、WordPressに標準で付属する検索機能はカスタムフィールドを対象としないため、カスタムフィールドのみを使用して記事を投稿した場合は、検索しても何もヒットせず使い物になりません。今回はこれを改善しようというものです。

何か良い策はないものかと調べてみると、

カスタムフィールドを検索対象に含める | WordPressカスタマイズ事典

に2つの方法が記載されていました。1つ目はfunctions.phpを書き換える方法、2つ目はプラグインを利用する方法です。今回は1つ目の方法でプログラムをそのまま書き換えてみました。そして、もう一度同じ文字列で検索してみると…

search_keyword2

おおお、ヒットしています。これはありがたい!

が、カスタムフィールドのすべてを検索対象としたときに、例えば”2015年の抱負”というページのカスタムフィールドの内容に”20189.jpeg”というファイル名が入っていた場合、2018年に投稿した記事を検索しようと”2018″と検索すると”2015年の抱負”が結果に表示されてしまいます。写真などのファイル名で訪問者が検索を行うというのは考えにくいので、ファイル名を内容とするカスタムフィールドは検索対象から除外することをおすすめします。私は検索文字列に関係のない投稿が結果に表示されて”ん?なぜだ??”となったまま悩み続けてしまいました…

それにしても検索できるって素晴らしい!

“地名生成ツール”の不具合について

ある日、”‘地名生成ツール’が動かない”という連絡があり、手持ちのAndroidで確認してみました。すると、FirefoxとChromeでは正常に動作し、ブラウザではボタンが表示されないことが判明したのです。

browser_place-name-generate

表示されるはずのボタンがありません。

その後PCのIEで見ても、これと同じことが起こっていました。この原因を調べた結果、以下の記述に問題があることが分かりました。

function button(bool,msg,obj=document.form0.button1) {
  obj.disabled = bool;
  obj.value = msg;
}

一見何の問題もないように見えますが、1行目の

obj=document.form0.button1

という記述が引っかかっていたのです。これは、引数を変数に代入するもので、変数objにはボタンオブジェクトをあらかじめ代入し、参照できるようにするはずでした。これを、

function button(bool,msg) {
  var obj = document.form0.button1;
  obj.disabled = bool;
  obj.value = msg;
}

とすると、うそのように解消したのです。どうやらこの記述方法は、AndroidのブラウザやInternet Explorerでは動作しません。

原因の解明には苦戦しましたが、修正できたのでよしとしましょう!

“地名生成ツール”を更新しました

“こーぐばこ”内の”地名生成ツール“を更新しました。変更点は以下の通りです。

  • 処理速度の向上
  • Twitter投稿用のボタンを設置
  • 文字の追加や削除

順に説明します。

処理速度の向上

生成地名数を10、20、30個の中から選択できた時代から残っていた不要な関数の削除や、処理方法を変更することにより、処理速度が向上しました。performance.now()を使用して生成時間を比較した結果、更新後は更新前よりおよそ40%短縮されていることを確認しました。

Twitter投稿用のボタンを設置

需要は0だと思われますが、面白そうだったので追加しました。”ツイート”ボタンを押した後、30個の生成結果の中から1つだけをTwitterに投稿することができます。

漢字の追加や削除

地名としては使われないような文字を削除し、”久”や”那”などの地名としてはよくある文字を追加しました。また、漢字ではありませんが”ケ”や”ノ”も追加しています。

削除

央,絵,各,閣,孔,交,行,豪,参,桟,支,首,臨,楼,湾,圃,坦,堵,塙,壬,夷,奄,娃,嵩,帖,庇,柾,棲,檀,汀,祇,笈,荻,蓉,蔭,祁,鵬,鱗,黎

追加

久,光,植,泉,浅,荘,那,奈,内,氷,鳴,緑,呂,ケ,ノ

変更

穏->隠(“かくす”の字を間違えていました)

その他

狩(二重に記述されていたため一方を削除しました)

結果39文字を削除、15文字の追加により24文字減の695文字となっています。その他多数の字の読みを変更しています。
もしも”この字を入れてほしい!”、”これはいらない!”というのがありましたら、お気軽にどうぞ。

一部のブラウザで正常に動作しないことが判明したため、修正を行いました。詳細を見る>>(2016/08/21)

JavaScriptでテストを作る

JavaScriptでテストを作成できる”examination.js”が完成し、“The Main Line”にて公開を開始しました。ダウンロード固定ページ“より”テストキット”を選ぶとダウンロードが可能です。

2020年11月03日より、”examination_v2.js”の配布を開始しました。一問一答が可能となったほか、いくつか改良を加えています。ダウンロード固定ページより、”テストキットv2″をご選択ください。v2について詳細を見る>>(2020/12/06)

このファイルは、以前に”The Main Line”で公開されていた駅名検定コーナーで使用するために作成したもので、それを配布用に改修しています。”examination.js”は採点などのプログラムや解答、点数の定義が含まれており、問題を表示するHTMLファイルと合わせるとテストが出来上がります。

主な仕様は以下の通りです。

  • 自動採点
  • 合格基準を、点数(~点以上)または問題数(~問以上)に設定することが可能
  • 解答表示
  • Twitter投稿用のボタンを表示(非表示にすることも可能)
  • 1つのグローバル変数”examination”を使用

こんな感じですかね。下の見本にもあるように、解答欄は入力(記述)と選択の2種類があり、選択肢を作らない分、前者のほうが作成は簡単です。

imgタグを使えば問題に画像を表示させることもできます。HTML5になり、inputタグではさまざまな種類の入力欄ができたので、新しいものを使うのも手ですね。

最後に、配布ファイルに同梱の”sample.html”の内容を見本として掲載します。”採点”ボタンを押すと結果が表示されます。

数字や英字、記号はすべて半角小文字で、それ以外は全角文字で記入してください。

1 : 入力方式(1問6点x5=30点)

次の問いに答えなさい。

  1. 1+1=
  2. (98+76)/(543-21)x0=
  3. この問題の点数は1問
  4. 円周率π=15926535…
  5. “日本”は英語(5文字)で

2 : 選択方式(1問4点x5=20点)

次の問いをよく読み、選択肢の中から正しい答えを選びなさい。

  1. アルファベットの最初の文字はである。
  2. 1000グラムは1である。
  3. 光の速さは音の速さ
  4. CO2とはの化学式である。
  5. 地球は系にある惑星の1つである。

合格の基準は、50点中30点以上に設定されています。

ダウンロード数のカウンタ

“The Main Line”のリニューアル時点ではまだ準備中だったBASICの配布ファイルですが、2016/05/14に公開を開始しました。1つ目は人生で初めて作ったプログラムである”数当てゲーム”、2つ目はスロット(のようなもの)です。JavaScriptコーナーにも、配布ファイルを置く予定となっているページがありますが、こちらは未だにほとんど進んでいません。ごめんなさい。

さて、BASICコーナーの配布ファイルのページには、ダウンロード数をカウントするカウンターが設置されています。これは私が自作したものですが、1つ難点があります。それは

クリックしただけで+1される

ということです。これは私の知識不足ではなく(と信じたい)、技術上どうしようもないことのようです。ブラウザではダウンロードするときに”キャンセル”を選ぶ画面が出てきますが、もうこの時点でPHPはすべての処理が終わっていると考えられます。また”キャンセル”を選んだとしても、PHPなどでそれを受け取る方法が存在しないため、必ず+1されてしまうのです。

以上、言い訳でした。

“The Main Line”の背景について

サイトの新しいページをhttp://ichiso.net/tml/にアップロードした後、パソコンとスマートフォン(Android)で確認を行ったわけですが、ここでちょっと困ったことになってしまいました。まずはこちらをご覧ください。(すべてAndroidのスクリーンショットです)

firefox_tml-top

この画像は、Firefoxでトップページを表示させたときのものです。ページ上端に4色の帯がありますが、これはSVGで作成した背景です。CSSのmarginによって、その帯かそれ以上の幅だけ文字を下げています。こうすれば、最初に表示したときに帯と文字が重ならなくなります。(スクロールすれば重なります)

firefox_tml-basic

では、ページの高さが変わればどうでしょう。ご覧の通り、帯の幅は変わりません。これは、ブラウザの画面の高さを100%とし、それに対する割合(ここでは5%)を帯の幅としたためです。どんなページを閲覧しようとも、ブラウザの画面の高さは変わらないので、この帯の幅も不変のはずです。

ところが、Google Chromeではそうはいきませんでした。

chrome_tml-top

同じトップページです。ブラウザの画面の高さはFirefoxと変わらないにもかかわらず、帯の幅が大きくなっています。

chrome_tml-basic

ページが長くなると、帯がぐんと大きくなります。このことから、Google Chromeに関しては”ブラウザの画面の高さ”が100%になるのではなく、”ページの高さ”を100%として計算してしまっているということが分かります。

Chromeの表示では明らかに帯と文字が重なっていますが、現時点では単位を変更したり、背景の表示をやめたりするといったことは考えていません。Firefoxのほうが正しい表示だと思うので、どうにかChromeに修正がかかることを祈るだけです…

なぜかform要素で送信できない

この前、とある用でファイルのアップロード用にページを作っていたのですが、どうしても送信できないという事態が起こりました。

<form enctype="multipart/form-data" action="index.php" method="post">
  <input type="hidden" name="MAX_FILE_SIZE" value="10000000">
  <p>アップロードするファイル : <input type="file" name="upload"></p>
  <p>ファイル名 : <input type="text" name="name"></p>
  <p><input type="submit" value="送信"></p>
</form>

簡単に書けばこんなコードですね。

このファイルは”index.php”として保存し、最初は順調にコーディングしていたわけですが、”送信”をクリックしても、何も起きないのです。最初は2行目の”MAX_FILE_SIZE”がおかしいのかと疑い直してみたものの、変化なし。

次に、もしかして<input type=”file”>のname属性に”upload”は使えないのか??と変な疑問が浮かび、変えてみるもやはり変わりません。

試しにprint_r( $_POST );と書いて結果を見ると、NULLに。

とうとう困り果て、一番上の行に目をやると、<form>のaction属性が”index.php”になっていることに気づき、”/”に変えたところ、思い通りに動作しました。

なぜ動作したかというと、このサイトでは例えば”http://example.net/index.php”でアクセスすると、”index.php”が省略されたURLに転送される仕様になっており、実際に見ているのは”http://example.net/”になります。action属性にあった”index.php”とは別のものとして扱っているらしく、動作しなかったらしいのです。

アップロードするページに”index.php”と名付けることはあまりないですが…

WordPressで、カスタムフィールドのみを使って記事を投稿する#2

#1の続きです。

準備に入ります。

1.カスタムフィールドの項目数と名前を決める

ただ名前を決めるだけですが、これが意外と重要です。考慮すべきことは、項目数は少なければ少ないほうがいいということです。欲張ってたくさん作ってしまうと、後々本文として表示するためにfunctions.phpを改造するときに進まなくなります。

#1で挙げた例では、

date
撮影日
info
写真の説明
photo
写真のURL

というようにして設定しています。

custom-field_post-new

投稿の新規追加画面で、右上にある”表示オプション”をクリックし、”カスタムフィールド”にチェックします。すると上の写真のようになります。

ここで、自分が決めたカスタムフィールドの名前と値を書き連ねていきます。例えば、ある人が毎日の起きた時間をひたすら投稿する、という単純なブログを作るとすると、

名前 : 起きた時間 / 値 : 6:00という具合です。

ここで注意したいのは、ここで決めたカスタムフィールドの項目は、後で変更しにくいという点です。変更できないわけではありませんが、functions.phpを書き直す必要が出てきます。

2.本文として表示するようにする

今の状態で”公開”をクリックしても、何も公開されません。それもそのはずです。本文には、エディターに書いた内容しか表示しないからです。

本文として表示させるには、content.phpを改造する必要があります。このファイルを開き、<div class=”entry-content”>と書かれた場所を探します。そこには、こうあります。

<div class="entry-content">
	<?php the_content( __( 'Continue reading <span class="meta-nav">→</span>', 'twentytwelve' ) ); ?>
	<?php wp_link_pages( array( 'before' => '<div class="page-links">' . __( 'Pages:', 'twentytwelve' ), 'after' => '</div><p>' ) ); ?>
</div>

これはtwentytwelveテーマの場合です。これを次のように書き換えます。

<div class="entry-content">
	<?php article_content( $post-> ID ); ?>
	<?php wp_link_pages( array( 'before' => '<div class="page-links">' . __( 'Pages:', 'twentytwelve' ), 'after' => '</div><p>' ) ); ?>
</div>

上下のコードを見比べると、まずthe_content関数がなくなっています。これはエディターから投稿する際に使う関数なので、カスタムフィールドのみを使う場合は必要ないからです。

次に、article_contentという謎の関数が組み込まれています。関数の名前はなんでもいいですが、引数には$post->IDを指定しておきます。

ちなみに、ここで内容を書くのではなく、わざわざ関数としているのは、RSSでの表示にもこの関数を使うためです。ここでget_post_meta( $post->ID , '起きた時間' , true );としても6:00と表示されますが、関数にしておいたほうが変更する際にも便利です。

次に、functions.phpを開き、article_contentという関数を作ります。

function article_content( $id ) {
    $time = get_post_meta( $id , '起きた時間' , true );
    echo "<p>起きた時間は" . $time . "です。</p>";
}

起きた時間を表示させるなら、例えば上のようになります。

カスタムフィールドに登録されたデータを取得するget_post_meta関数の引数は、

第1引数
取得するメタデータの投稿ID
第2引数
カスタムフィールドの名前(日本語も可)
第3引数
戻り値を文字列とするか配列とするか。trueで文字列、falseまたは何も書かなかった場合は配列

となっています。

もしも、自分が起きた時間を”12:00″、ペットのポチが起きた時間を”不明”として、カスタムフィールドの値を”12:00,不明”と書いたとしましょう。そうすると、表示されるのは起きた時間は12:00,不明です。となってしまいます。”12:00″と”不明”を分けて表示するには、

function article_content( $id ) {
    $time_array = explode( ',' , get_post_meta( $id , '起きた時間' , true ) );
    echo "<p>私が起きた時間は" . $time_array[0] . "で、ポチが起きた時間は" . $time_array[1] . "です。</p>";
}

のようになります。PHPのexplode関数を使って、コンマで区切られた値をそれぞれ分けて配列にします。配列$time_arrayには、0番目の要素に”12:00″が、1番目の要素に”不明”が入ります。

これで投稿を表示することが可能となりました。

3.RSSにも表示するようにする

最後にRSSです。RSSには本文と同じ内容を表示するものとして考えます。

方法は簡単で、functions.phpに

function child_the_excerpt_rss() {
	return article_content( get_the_id() );
}
add_filter( 'the_excerpt_rss' , 'child_the_excerpt_rss' );

を書き足すだけです。フィルターthe_excerpt_rssは、WordPress Codexによると

投稿の抜粋を RSS フィードに含める前に適用される。

とあります。もしも投稿とRSSの内容を別々にする場合は、別の関数か内容を書くといいでしょう。

これで完成です。これで、起きた時間を書くだけで投稿が出来るようになります!

おまけへ

WordPressで、カスタムフィールドのみを使って記事を投稿する#1

WordPressは、GPLというライセンスで配布され、いくらでもサーバーにインストールできることから、たくさんのブログを作ることが可能です。そんなブログの中には、写真や文章の組み合わせが固定され、コードはどの投稿も大して変わらない、ということがあるかもしれません。

そんなときに味方になるのが、カスタムフィールドです。投稿ごとに変わる内容を記述するだけで、1つの記事を完成させることが出来ます。記述された内容は、あらかじめfunctions.phpに書かれたコードに流し込み、それを表示するという仕組みにすればいいわけです。

blog-ekidori

これがその利用例です(第一駅撮区)。投稿の全体を写すため縮小しています。

この画像内の”紀伊勝浦 -> 紀勢本線”とあるのがタイトルで、”撮影日 : 2014/09/21″が投稿の終わりです。このブログの投稿はすべてこんな感じで、写真とその説明のセットが何回か繰り返され、写真の撮影日を表示して終了しています。

このようなブログの場合、コードは大体決まったものになってきますので、工夫次第では1回の投稿で要する時間を短縮することが可能です。

blog-ekidori_post-new

次にこの投稿の編集画面を見てみましょう。カスタムフィールドが3つ見えます。投稿する際は、ここに内容を入力します。

ところで、撮影日は1回しか表示しませんが、写真とその説明の表示数は、写真の数によって変わります。このように2枚しかないときもあれば、逆に撮りすぎて10枚くらい追加したくなるときもあります。

この場合、ここでは、写真であれば写真を、説明であれば説明をそれぞれコンマ”,”で区切って記述し、1番目に書いた写真のURLと説明を、2番目に書いた写真のURLと説明を…というように要素を対応させて表示することで達成しています。

開発当初は、1つの写真とその説明のセットで1つのカスタムフィールドを充てようとしたのですが、そうすると10枚写真を追加したくなったときに、10回分のカスタムフィールドを作らなければならなくなるため、結局このようになりました。

このようにすることで、以下のような利点があります。

  1. 投稿にかかる時間を短縮できる
  2. 後で編集するために見返したとき、不要な部分がないため見やすい

逆に、欠点もあります。

  1. 投稿やRSSに表示させるために、コードを書き足さなければならない
  2. 内容に区切り文字が含まれていると、投稿内容がおかしくなる

欠点の2番目は、区切り文字を投稿内容に使わない文字に変えることで解決します。問題は1番目です。

カスタムフィールドは本来、特別なデータを扱うためのものであり、本文として表示するにはコードを書き足す必要があります。手間にはなりますが、長い目で見れば得になるはずです。

それでは次の記事より、カスタムフィールドのみを使った投稿の準備について続けていきます。

#2へ