Contents
WORDPRESS + JQUERY AJAX + PYTHON + JSON で再度苦労してみた
動機
「WordPress + jquery ajax + Python + json で苦労してみた」は write-only なので、まぁ、ネタとして不十分で面白さは半分。入力がある、一般ケースで遊んでみた。
サンプルに使えそうなネタはお手持ちだのね
命名規則のための名前変形処理@Python、和英混在文書の表記ゆれ統一のために unicodedata.normalizeな。
テキストボックスを入力に、で、変形結果を出力すれば良いね。
コードはこれだけ
まず、サーバで動作する、json を返す Python で書いた「cgi」:
1 #! /usr/bin/python2.7
2 # -*- coding: utf-8 -*-
3 import re
4 import unicodedata
5 import sys
6
7
8
9 def _normalize(src):
10 def _repl(m):
11 s = m.group(1)
12 return {
13 u'\u201d': '"',
14 u'\u2019': "'",
15 u'\u2018': "`",
16 }.get(s, s)
17 return unicodedata.normalize(
18 'NFKC',
19 re.sub(ur"([\u201d|\u2019|\u2018])", _repl, src))
20
21
22 #
23 #
24 #
25 def _split_into_words(s):
26 result = []
27 spl = re.split(r"[ _]", s)
28 for w in spl:
29 inner = \
30 re.sub(
31 r"([A-Z]+)([A-Z])([a-z0-9]+)",
32 r"\1,\2\3",
33 re.sub(r"([a-z0-9])([A-Z])", r"\1,\2", w)
34 ).split(",")
35 for i, ins in enumerate(inner):
36 if not re.match(r"^[A-Z]+$", ins):
37 inner[i] = ins.lower()
38 result.extend(inner)
39 return result
40
41
42 #
43 #
44 #
45 class BaseNameMangler(object):
46 def __init__(self, s):
47 self._splitted = _split_into_words(s)
48
49 def convert(self, dest_type="capWords"):
50 """
51 >>> c = BaseNameMangler("simpleHTTPServer")
52 >>> c.convert("CapWords")
53 'SimpleHTTPServer'
54 >>> c.convert("capWords")
55 'simpleHTTPServer'
56 >>> c.convert("lower_underscore")
57 'simple_HTTP_server'
58 >>> c.convert("upper_underscore")
59 'SIMPLE_HTTP_SERVER'
60 >>> c.convert("CapWords_force")
61 'SimpleHttpServer'
62 >>> c.convert("capWords_force")
63 'simpleHttpServer'
64 >>> c.convert("lower_underscore_force")
65 'simple_http_server'
66 >>> c = BaseNameMangler("simple_HTTP_Server")
67 >>> c.convert("CapWords")
68 'SimpleHTTPServer'
69 >>> c.convert("capWords")
70 'simpleHTTPServer'
71 >>> c.convert("lower_underscore")
72 'simple_HTTP_server'
73 >>> c.convert("upper_underscore")
74 'SIMPLE_HTTP_SERVER'
75 >>> c.convert("CapWords_force")
76 'SimpleHttpServer'
77 >>> c.convert("capWords_force")
78 'simpleHttpServer'
79 >>> c.convert("lower_underscore_force")
80 'simple_http_server'
81 >>> c = BaseNameMangler("HTTP_Server")
82 >>> c.convert("CapWords")
83 'HTTPServer'
84 >>> c.convert("capWords")
85 'HTTPServer'
86 >>> c.convert("lower_underscore")
87 'HTTP_server'
88 >>> c.convert("upper_underscore")
89 'HTTP_SERVER'
90 >>> c.convert("CapWords_force")
91 'HttpServer'
92 >>> c.convert("capWords_force")
93 'httpServer'
94 >>> c.convert("lower_underscore_force")
95 'http_server'
96 """
97 if dest_type == "CapWords":
98 return "".join([
99 s.title() if s[0].islower() else s
100 for s in self._splitted])
101 elif dest_type == "capWords":
102 return "".join([
103 s.title() if i > 0 and s[0].islower() else s
104 for i, s in enumerate(self._splitted)])
105 elif dest_type == "lower_underscore":
106 return "_".join(self._splitted)
107 elif dest_type == "upper_underscore":
108 return "_".join([
109 s.upper()
110 for s in self._splitted])
111 elif dest_type == "CapWords_force":
112 return "".join([
113 s.title()
114 for s in self._splitted])
115 elif dest_type == "capWords_force":
116 return "".join([
117 s.title() if i > 0 else s.lower()
118 for i, s in enumerate(self._splitted)])
119 elif dest_type == "lower_underscore_force":
120 return "_".join([
121 s.lower()
122 for s in self._splitted])
123
124
125
126 # ----------------------------------------------------------------------
127 import json
128
129 sys.stdout.write("Content-Type: application/json")
130
131 sys.stdout.write("\n")
132 sys.stdout.write("\n")
133
134 form = json.loads(sys.stdin.read())
135 src = form["src"]
136 typ = form["type"]
137 c = BaseNameMangler(_normalize(src))
138
139 result = {}
140 result['success'] = True
141 result['dst'] = c.convert(typ)
142
143 sys.stdout.write(json.dumps(result, indent=4))
144 sys.stdout.write("\n")
145 # ----------------------------------------------------------------------
「#! /usr/bin/python2.7」はレンタルサーバの関係で。
で、Wordpress からは、記事にショートコードで
1 [simple_namemangler_js]
と書くだけでいいようにしたかったのと、あとは
SkyScanner
で経験したやり方、これしか今 WordPress に script を貼り付ける方法を知らない(いわゆるバカの一つ覚え)ということもあり、functions.php に以下を追加:
1 /**
2 *
3 */
4 function simple_namemangler_js_handler($atts, $content=null) {
5 $str=<<<eot
6 <style type="text/css">
7 .mangled {
8 background-color: #fcfcff;
9 color: #000055;
10 font-size: x-large;
11 font-style: bold;
12 text-align: center;
13 margin: 0.3em;
14 padding: 1.2em;
15 border-style: solid;
16 border-width: 1px 1px 1px 1px;
17 border-color: #0000cc;
18 }
19 </style>
20 <script type="text/javascript" src="/site-hhs/wp-includes/js/jquery/jquery.js"></script>
21 <script type="text/javascript">
22 jQuery(function($) {
23 function do_mangle() {
24 $.ajax({
25 url: "/cgi-bin/simple_namemangler_cgi.py",
26 type: "post",
27 data: JSON.stringify({'src': $('#src').val(), 'type': $('#type').val()}),
28 dataType: "json",
29 success: function(response) {
30 $("#dst").html(response.dst);
31 },
32 error: function(xhr, status, error) {
33 //alert(xhr.responseText);
34 }
35 });
36 };
37
38 $(document).ready(function() {
39 do_mangle();
40 $('#src').on('change', function() {do_mangle()});
41 $('#type').on('change', function() {do_mangle()});
42 });
43 });
44 </script>
45 <form>
46 <input type="text" id="src" name="src" size="40" value="Python HTTP jquery ajax json">
47 <select name="type" id="type">
48 <option>CapWords</option>
49 <option>CapWords_force</option>
50 <option>capWords</option>
51 <option>capWords_force</option>
52 <option>lower_underscore</option>
53 <option>lower_underscore_force</option>
54 <option>upper_underscore</option>
55 </select>
56 </form>
57 <div id="dst" class="mangled"></div>
58 eot;
59 return $str;
60 }
61 add_shortcode('simple_namemangler_js', 'simple_namemangler_js_handler');
一度成功したくらいじゃ、ハマらなくなるわけじゃないね
所要時間は2時間くらいだもん、大した苦労でもないけれどね、でも10分で仕上げる気だったんだ、随分な苦労だわな。
以下2つの行き来:
1 jQuery(function($) {
2 function do_mangle() {
3 $.ajax({
4 url: "/cgi-bin/simple_namemangler_cgi.py",
5 type: "post",
6 // ___ここ↓
7 data: JSON.stringify({'src': $('#src').val(), 'type': $('#type').val()}),
8 // ___ここ↑
9 dataType: "json",
10 success: function(response) {
11 $("#dst").html(response.dst);
12 },
13 error: function(xhr, status, error) {
14 //alert(xhr.responseText);
15 }
16 });
17 };
1 form = json.loads(sys.stdin.read())
なのね、核心は。というかここだけ。「JSON.stringify」部分はPost JSON to Python CGI | Stack Overflowを参考にした。
あと下らない ImportError (import sys 忘れた) とかもあったけどね。