WordPress + jquery ajax + Python + json で苦労してみた

WordPress + jquery ajax + Python + json で苦労してみた

fortuneを作ってみた。



動機

単なる知的好奇心、または私は如何にして心配するのを止めて水爆を愛するようになったか。

でもなくて。WEB系は業務での経験がかなり少なくて、たまに必要なたんびに苦痛だったもんで、ちょいと仕事でない時間で気楽に苦労しとこうかと。

コードはこれだけ

まず、サーバで動作する、json を返す Python で書いた「cgi」:

 1 #! /usr/bin/python2.7
 2 # -*- coding: utf-8 -*-
 3 import os
 4 import sys
 5 
 6 def random_int(start, end):
 7     import random
 8     try:
 9         # Use SystemRandom, if it's available, since it's likely to have
10         # more entropy.
11         r = random.SystemRandom()
12     except:
13         r = random
14 
15     return r.randint(start, end)
16 
17 def get_random_fortune():
18     import cPickle as pickle
19 
20     fortune_file=os.path.join(os.path.abspath(os.path.dirname(__file__)), "fortunes")
21 
22     fortune_index_file = fortune_file + '.dat'
23     if not os.path.exists(fortune_index_file):
24         raise ValueError, 'Can\'t find file "%s"' % fortune_index_file
25 
26     with open(fortune_index_file) as fortuneIndex:
27         data = pickle.load(fortuneIndex)
28     randomRecord = random_int(0, len(data) - 1)
29     (start, length) = data[randomRecord]
30 
31     with open(fortune_file, 'rU') as f:
32         f.seek(start)
33         fortuneCookie = f.read(length)
34 
35     return fortuneCookie
36 
37 # ----------------------------------------------------------------------
38 import json
39 #import cgi
40 
41 sys.stdout.write("Content-Type: application/json")
42 
43 sys.stdout.write("\n")
44 sys.stdout.write("\n")
45 
46 result = {}
47 result['success'] = True
48 result['fortune'] = get_random_fortune().replace("\n", "<br/>").replace(" ", "&nbsp;")
49 
50 sys.stdout.write(json.dumps(result, indent=4))
51 sys.stdout.write("\n")
52 # ----------------------------------------------------------------------

#! /usr/bin/python2.7」はレンタルサーバの関係で。「get_random_fortune」あたりはこの投稿参照。別に難しくない。

で、Wordpress からは、記事にショートコードで

1 [fortune_js]

と書くだけでいいようにしたかったのと、あとは
SkyScanner
で経験したやり方、これしか今 WordPress に script を貼り付ける方法を知らない(いわゆるバカの一つ覚え)ということもあり、functions.php に以下を追加:

 1 /**
 2  *
 3  */
 4 function fortune_js_handler($atts, $content=null) {
 5 $str=<<<eot
 6     <style type="text/css">
 7     .fortune {
 8         background-color: #fcfcff;
 9         color: #000055;
10         font-size: small;
11         font-style: italic;
12         margin: 0.3em;
13         padding: 1.2em;
14         border-style: solid;
15         border-width: 1px 1px 1px 1px;
16         border-color: #0000cc; 
17     }
18     </style>
19     <script type="text/javascript" src="/site-hhs/wp-includes/js/jquery/jquery.js"></script>
20     <script type="text/javascript">
21     jQuery(function($) {
22         function load_fortune() {
23             $.ajax({
24                 url: "/cgi-bin/fortune_json_cgi.py",
25                 type: "post",
26                 dataType: "json",
27                 success: function(response) {
28                     $("#fortune").html(response.fortune);
29                 },
30                 error: function(xhr, status, error) {
31                     //alert(xhr.responseText);
32                 }
33             });
34         };
35 
36         $(document).ready(function() {
37             load_fortune();
38             $('#refresh').on('click', function() {load_fortune()});
39         });
40     });
41     </script>
42     <a id="refresh">&gt;&gt;&gt;</a>
43     <div id="fortune" class="fortune"></div>
44 eot;
45     return $str;    
46 }
47 add_shortcode('fortune_js', 'fortune_js_handler');

出来上がってしまえばなんてことはないが

ハマりポイント多数。

普通にパーミッションの問題にハマっておったし。ディレクトリを潜れずにエラーになっていたが、「WEBプログラミングに不慣れ」なので、デバッグの仕方もわからず。

1     error: function(xhr, status, error) {
2         //alert(xhr.responseText);
3     }

はその痕跡。これに辿り着いてようやくパーミッションの問題とわかった。

Pythonスクリプトにも問題があって、import がね、うまくいかなかったですとよ。「fortune.py」を独立させておきたかったけど。これは環境によるでせう。

あとな、「はじめての jquery」なわけですよ、ほぼ(しかも一昔前の prototype.js さえも、もっといえば javascript にも暗い)。だもんで、jQuery(function($) {からして悩む、ブラウザが何をするイベントにどう反応するのがセオリーなのか(ready)みたいなことにも「うとい」んであって、「デバッグ仕方がワカラン」とあいまって、右往左往。あぁ楽しかった。

「苦労」ではなくて、個人的に「あぁ、javascript ってそうなんだ」と思ったのは

1     $('#refresh').on('click', function() {load_fortune()});

部分で、それは「on の使い方」や「セレクタとは」の話ではなくて。

1     $('#refresh').on('click', load_fortune());

と書いて動かなくて悩んだのであった。うーん?? Python とかの感覚だと「匿名でない名前付き関数を素直に渡している」つもりなのであって、function() {} で囲まないと動かない、などとは夢にも思わない。そうかそうなのか。

あとは、

1 <script type="text/javascript" src="/site-hhs/wp-includes/js/jquery/jquery.js"></script>

と書かなくていい方法を探るも、これは正解出てない。んー。



2015-06-19追記

WP Category Tag Cloud がぶっ壊れたのと同じ原因で色んな道具が壊れたをご覧ください。