tag:blogger.com,1999:blog-3188302565422275282024-02-07T14:33:30.964+08:00marr webloglearning to lead a life of awareness.marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.comBlogger340125tag:blogger.com,1999:blog-318830256542227528.post-21939314134965587552019-10-03T11:41:00.002+08:002019-10-03T12:05:55.893+08:00Odoo ERP Calendar<img src="https://lh3.googleusercontent.com/0RiyMJX5iu2C_PiA351qoQw_uMq3ZknAT6YqAl2LlhDUL5BjCcFPFSsGNEl7TDKgARXdx5DXho72mBWXjQKpd6u11pU4e89ABBqx6zr7RpQOWxKVD5sGlTbF5jw7MRRyNeJt--CoffPA-LVonvCbn8izOXte6VKeLcIyYbexd_gkxV65hyg156bGPufd5GXw6XjtwAMSY5uLhsMqBAhV3Dr9xRBpT7kav0p1xtZUJpUdKqY-InBpQ4xjxYMoWlNz-uxykKwMOrTb99Yfl5jA_uSg5eEU_UjUZIxgNKU2nr_uO_uOB9sOgzbEUUa7dF3AR79pLZqKd25x_2t-FxGTRWnuIt-shN-ejLbq1sswDlqwzEw7yxZb3kIJdf327elETSdeYRW6-UB6uT3BVQIg0gDJt8z_w7hY4piq8S9u_GZ5OVkZmcmz0ZDovhWFrbvW3ccEAxDWAGxLtJvwSakHUBz-6sawsbzPzUmhTkTurqKOkXsmb8wech_Gg1XQ40tRtJgTsMGlBBqYSQ04cct4LNhM_0MRSYDZP7nM0luNO7LDhjhPf5XadGKrptsqc4sTiu50iI6o9CM2gl6qy1dlwpCyRrghQiPWLHfL6PC_rPHXVo0AF7EZsWTiyYZAySLfRZy7czPlpgbacfQ_McDZ-hElO_24zqhKYeFQFMeECK5GFVvVtwON8-w=w599-h137-no" />
<p>這是一篇測試記錄,針對 Odoo 社群版剛安裝好的情境,導入 demo 資料,啟用 Calendar 模組,先觀察基本功能,再設定 Google Calendar 整合。</p>
<img src="https://lh3.googleusercontent.com/L5js1-JOWAG8TLW1aMJCGXZxsyp0dBf2ZS8YIeauF-iMCj58MOnJnc9uOStXWO6xYuOhJRwxb6y8hvLp_MG0uO-xEsgyzeah8B0ZUF4Kt6eS0rt1vFB9Z3FAe-W-Ov5jO8WaXhpWygVa3zsDXLPnZP4rkhVVkuBzkTOpPSTdIu2Ch0Nmg2UAjkkBSaeP-uBNIHrov_cEVki37c_DSb-MzFoLvMOa_FpQkJz7QSsHL5qFipgDHhsKOUIe7xZ6Ugy0x-P_ymMnDJcwZ8aRdyfMjLZHeewNjVwuzDb1vLdgQXwpO-njrzk_ISstDnJgHdDCFEU-OhcxqaTP19McwU0C7hS8tibkgW7qu7-n5pSiAS-gqfAzGJj69QCaIrnOFdMf_5aXxbvJez4u82BFGC_m43KJWOwYrgk-B5_NGx-paZC4VzWoKPXxuRA0ai5236GvOPKOut7CKK-zt6zdTp0tqNnmAlj21xQWiGFpz0Y1iul6i_LxjLrpZSqWJPbInnK-Z7u7De_kl5tLY26b91850vbWC5p6ZIBiXRP623IN8oLSgmdJacGZWBcxDbnAK4lrj8zn0QdMaDYA-SAXc2ejzpoXdXUFj-YLuYhlwRM5C0XJ4vZpU6qOzf-HZttYNzl0W-HxomNmj4VD8HHAyw4vj1Utf2rrND4TfvmmcYiXkydiOUZ7tMXfwdE=w396-h232-no" />
<p>啟用 Calendar 會自動啟用 Discuss 模組,右上方 Conversations 有個 Push Notification 啟用請求,啟用後可以觀察系統通知的運作方式。</p>
<p>從 Settings / Dashboard / Users 看得到兩個帳號 Mitchell Admin 和 Marc Demo,但 Demo Meeting 的 Attendees 資料還包括 Wood Corner 之類的人員資料,很好奇是塞到哪個資料表裡,初步找到 odoo/addons/base/data/res_partner_demo.xml 裡有這筆資料,裡頭發現 res_partner 還分成 category, address, main 之類的細節。</p>
<img src="https://lh3.googleusercontent.com/36RxbjJ3vh0uaDftIS3F8t5ppM2KT9OQMdYFKK-ncjDi27Cn19fLE_uyjjzT8IeOJ7jqwjunJW6WpRLE8kmO8bB_aQQhlHUhG-_qbSi2xI9GcX8CdmOyi5dsoDJj6hOCy1wBIwLpfZoFe3PKViA-KSq1EMdtP_QjezYIaAroZoHPtACmeNtK7QehqFhpcYMr4PpR2J0IpTO_fJZb3fzHbMZo-bNChHHccV9zT-mbOaq4D9yOVCmdGwYfWa1Lxl5y3q1hO_eEG9-GJ-C9-m0T0wxy4mQnIds5-2QJAR11EV3Y4LXpkQnxLeU8s04qSCT6N1SPeKYx6IhLWlwGk5e-kGqt1qSQ-zqRMemCKmcM3DA-7J1L-cBH0fHxCkXoGLlbCVwd-dVaXz0PCma2xArJQkVOTTBKe8_-1f4PjRDJ_W4w-MrzP5B-mB0mX7-e1mH9nqEBpn2YU3ZiGS-jM86N2Pj5YipfIs0lFIWBQQPKN_Pi0_knNd21saE2mvwQ34jh9tvEzxtAua-dB1gJ059LCobajkw_BzY3k7xDtY32TKZHpVDR-EaqZ9q1SC-Yv7iRfyyiNM_7bsmt-DxCb_uTvd_KhFr4dxs7IiQx00EajCErmrICHD2M471LB_CWoQNP9IGrxip4u6pbZk_K2Ti0lgCkl3JcQf82MaRessuV9eE92uaQhiX9rr8=w920-h527-no" width="100%" />
<p>傳統 Calendar 功能是為了 Meeting 新增和管理,欄位包括 Location, Duration, Description 等,編輯時有看到 Attendees 欄位,但找不到 Responsible 欄位,只知道 Responsible 可以用來當顯示 Meeting 的過濾條件,但還不清楚 Responsible 的設定方法。</p>
<p>Calendar 的瀏覽方式分成 Calendar 和 List 兩種畫面,當月曆功能跟 CRM 之類的其他模組整合時,其他模組也會出現 Calendar 畫面,但 Meeting 資料不會被同步顯示,從這角度來看,我覺得 Calendar 改稱 Meeting 更為精準才對。</p>
<img src="https://lh3.googleusercontent.com/udwrT2oXxILSvDAAHY_MLouYnoULOWba7CRqdNHnZJCpVqF7Xkq1OdEcDXpGmWXv-q4yHWjyHcMtn2dLyrux1fR1YW61zIrjAQvQhHqlT7HHCBezFy5VQCOchZ5gqsRhsp1BvYv7UJBX9DJeRZzn9Kt2zfBbnjhGBV6xkpz5ecby8AORNWGpxk3w8YWjwcDhrNJYg0ITb9KtefWBKzXnSTqnzZfAIexBKHWDZrucUgckkwDpHyvzyuSt4qPhfFgX71qibjctH2xsDVDsIGr5dWqhQRHX0TRrdu7gHe3ggYT8wwTaLJ6UU9SCHYdGCsO_GfbCF24Z8rEPLQbV_7UcNBqBgQzGqYf27-xlTung_AEa-1sdGHtm-YrK0ooja_5uOVPqUbUNyJ4zDzKpjIlfT6-ObHh3RTjmXAHXGXVMl7RCCtIctypAa1eDZVt8WgLuNM2i-GLRT6-iDx4P6U3pLWv-8GpJN_nsqQfUpedgbVXfaZuaSgDpunpCH83Bv2eK0HP4valeUgYt0qsfxQl2YSk0gAKQNBLxuY8d0g0VgKW6xle2QAImGHCfeMl9BGvGQCA9x49aMlweGQI0mhRORSP6y9MRq3ci6eHULxe_K4vN09GKo0Q9msfjp8fORb7mbP1iZzz7RTuxsi-DNDu_G9ckokU3vv-zh9N73wz1KsIQnv1K7-ExMwM=w920-h220-no" width="100%" />
<p>從 Settings / General Settings / Integrations 可以指定 Google Calendar 整合設定,需要填寫 Client ID 和 Client Secret 兩個欄位,因為 Google Console 畫面已經跟<a href="http://technaureus.com/synchronize-google-calendar-with-odoo">線上</a>文件呈現不吻合,初步猜測要在 Google APIs & Services / Credentials / Key restrictions 選擇 HTTP referrers (web sites) 再設定。測試網站要有對外 IP 才能整合設定,沒找到偷懶的辦法。</p>
<img src="https://lh3.googleusercontent.com/PUBVQNs_FyrZWMqR-CFQrk1I5_WaCsxvUL1N8Ulm9ttkhGOJNA2ff18PQL0EAoMBEn_tTUz9BnWMwa0Ma2LTRnacy15fsSkvgO5euPN6ho1P6ppmpwm8I1F_UJ9lbnjxI11ONUjsL96xkLDnv9L1YJjHZfSl_nj0AqZyyINgUYCLjDkdKGRwwdy1oXP2eifnMJSi7iYCyfeNdj5jvfqijGtaIiDUYxu33jugxxhCAg49jTAuv2EcDJ3TDR5butmryNb4BUUgg-4ioe48HrQQQTjBIu0HB0E9zliU-0InAwYe_iJ4TBCM4vCelgZ1NIJnN_KYxrw8z-AOw6fglAZgkJHEXjh6zCnSWYo6q9Z0Jd10EE2Hte8YdA5J9428mc3US7U4FUvtBV8dt4pb9rLFRE1xYhxAFEsOrpT7FivphBrl7eLBtaDw8yhFCSO07s8_CLrRQZy8WaguQ-qsSg5AAyCei_GTQdje3JYRpon5CfV9D8N39fsMR7rVHhHWiGz6kk2OBvz1XstiKYUJnCOM_IH3KlUT8kVT44LeXdN9TVXtBSiquEGFACOJ9JWAgHauoedz1dKsQ7BOKNLHO-20b8wa-e8wLMANqHaVeuQxKr6R809tgTfNAgNN4aEQnVCiUMCMNe2LOQU-0sC0OhantL-AECUOWAyq3FoFEX8P2r9Lzp3h5lOc8yE=w881-h360-no" width="100%" />
<p>如果想要把 Meeting 整合 Task 來用,還要額外啟用 CRM 或 Project 模組,再找時間研究它們的整合情況。</p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-85294384383546787092018-09-26T10:40:00.000+08:002018-09-26T10:40:27.227+08:00Plone5 New Features<p>對網頁技術人員而言,多少都要接觸 Javascript 語言衍生的生態圈,為了和這股潮流接軌,新版 Plone 透過 Mockup 讓 Javascript 客戶端的整合,變得更容易。這個導入及轉換工作,採用 PatternsLib 設計概念,會逐步改寫 Plone 的服務工具,例如 <a href="http://marrtw.blogspot.tw/2015/02/plone-widgets.html">plone.app.widgets</a> 和 plone.app.toolbar 這兩個模組,是利用 Mockup 機制做出的成果範例。</p>
<p>多國語系的支援是透過 plone.app.multilingual 模組,它在 Plone 4.3 時代就存在,新版環境就是預設安裝,啟用後就能套用。下列是批次匯入內容的範例:</p>
<pre>#!/usr/bin/python
# -*- coding: utf-8 -*-
from Testing import makerequest
from AccessControl.SecurityManagement import newSecurityManager
from Products.CMFCore.utils import getToolByName
root = makerequest.makerequest(app)
site = root.mysite
admin = root.acl_users.getUserById('admin')
admin = admin.__of__(site.acl_users)
newSecurityManager(None, admin)
from zope.site.hooks import setHooks
from zope.component.hooks import setSite
setHooks()
setSite(site)
site.setupCurrentSkin(site.REQUEST)
from plone.dexterity.utils import createContentInContainer
from plone.app.multilingual.interfaces import ITranslationManager
from plone.app.multilingual import api as pamapi
from plone import api as ploneapi
from Products.CMFPlone.interfaces import ILanguage
from plone.dexterity.utils import iterSchemata, iterSchemataForType
#from plone.rfc822 import constructMessageFromSchemata
#from plone.rfc822 import initializeObjectFromSchemata
import csv
def unicode_csv_reader(utf8_data, dialect=csv.excel, **kwargs):
csv_reader = csv.reader(utf8_data, dialect=dialect, **kwargs)
for row in csv_reader:
yield [unicode(cell, 'utf-8') for cell in row]
wftool = getToolByName(site, 'portal_workflow')
with open('/home/marr/plone511/zinstance/csv_script/item.csv', 'rb') as f:
dialect = csv.Sniffer().sniff(f.read(), delimiters="\t")
f.seek(0)
reader = unicode_csv_reader(f, dialect)
for row in reader:
folder = site.en.events
item = createContentInContainer(folder, 'Event', title=row[3])
oldid = item.id
# language = ILanguage(item).get_language()
# print language
manager = ITranslationManager(item)
manager.add_translation('en')
en = manager.get_translation('en')
# manager.register_translation('en', en)
en.title = row[3]
en.description = row[4]
manager.add_translation('zh')
zh = manager.get_translation('zh')
zh.title = row[1]
zh.description = row[2]
ploneapi.content.delete(obj=item)
# site.en.events.manage_renameObject(oldid, str(row[0]))
# site.zh.events.manage_renameObject(oldid, str(row[0]))
#wftool.doActionFor(site.en.events[str(row[0])], 'publish')
wftool.doActionFor(en, 'publish')
#wftool.doActionFor(site.zh.events[str(row[0])], 'publish')
wftool.doActionFor(zh, 'publish')
en.reindexObject()
#print row[0] + " en done."
zh.reindexObject()
#print row[0] + " zh done."
#print pamapi.get_translation_manager(item).get_translations()
import transaction
transaction.commit()</pre>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-10543516707951169682018-09-04T21:20:00.004+08:002018-09-05T20:58:31.676+08:00Archetypes Migration to Dexterity<h2>Link Integrity Check</h2>
<p>Be sure to set it disabled</p>
<h2>Image Attributes in RichText Fields</h2>
<pre><p><img class="image-inline" title="開基武廟外觀" src="kjwm-wg.jpg/@@images/c57ff855-3d5e-4eaf-8e5c-5e32db58867e.jpeg" alt="開基武廟外觀" /></p>
<p>開基武廟外觀 謝奇峰拍攝2011.8.6</p>
<p><img class="image-inline" title="開基武廟前殿" src="kjwm-qd.jpg/@@images/9c0d6de5-3295-49a5-970d-e26f51b117d6.jpeg" alt="開基武廟前殿" /></p>
<p>開基武廟前殿 謝奇峰拍攝2011.8.6</p>
<p><img class="image-inline" title="開基武廟前殿神龕" src="kjwm-qdsz.jpg/@@images/42c54979-0cad-4244-b692-80d736e25f77.jpeg" alt="開基武廟前殿神龕" /></p>
<p>開基武廟前殿神龕 謝奇峰拍攝2011.8.6</p>
<p> </p>
<p><img class="image-inline" title="開基武廟後殿" src="kjwm-hd.jpg/@@images/e74bc633-d278-47bd-8c13-223c16c1e5eb.jpeg" alt="開基武廟後殿" /></p>
<p>開基武廟後殿 謝奇峰拍攝2011.8.6</p>
<p><img class="image-inline" title="開基武廟後殿之三川殿" src="kjwm-hdscd.jpg/@@images/4919cf95-a664-48c1-a0d7-5cef3b91c4a3.jpeg" alt="開基武廟後殿之三川殿" /></p>
<p>開基武廟後殿之三川殿 謝奇峰拍攝2011.8.6</p>
<p><img class="image-inline" title="開基武廟後殿之拜殿" src="kjwm-hdbd.jpg/@@images/66b3e3e9-7be7-4513-beff-53b1a70bba18.jpeg" alt="開基武廟後殿之拜殿" /></p>
<p>開基武廟後殿之拜殿 謝奇峰拍攝2011.8.6</p>
<p><img class="image-inline" title="開基武廟後殿之正殿" src="kjwm-hdzd.jpg/@@images/76e89581-2bf4-4410-b08e-05882fada26d.jpeg" alt="開基武廟後殿之正殿" /></p>
<p>開基武廟後殿之正殿 謝奇峰拍攝2011.8.6</p></pre>
<pre>import re
text_list = html_doc.split('\n')
result = []
for text in text_list:
find = re.search(r'(^.* src\s*=\s*")(.*\.jpg/@@images/)(.*\.jpeg")( alt=.*$)', text)
if find:
result.append(find.group(1) + find.group(2) + 'image/preview"' + find.group(4))
else:
result.append(text)
print '\n'.join(result)</pre>
<p>利用 bin/plonectl run update.py 來更新 RichText 內容</p>
<pre>#!/usr/bin/python
# -*- coding: utf-8 -*-
from Testing import makerequest
from AccessControl.SecurityManagement import newSecurityManager
from Products.CMFCore.utils import getToolByName
root = makerequest.makerequest(app)
site = root.mysite
admin = root.acl_users.getUserById('admin')
admin = admin.__of__(site.acl_users)
newSecurityManager(None, admin)
from zope.site.hooks import setHooks
from zope.component.hooks import setSite
setHooks()
setSite(site)
site.setupCurrentSkin(site.REQUEST)
import re
from plone import api
from plone.app.textfield.value import RichTextValue
import transaction
for item in api.content.find(Type='MyType'):
obj = item.getObject()
if obj.myfield == None:
text = []
else:
text = obj.myfield.raw.split('\n')
result = []
for line in text:
find = re.search(r'(^.* src\s*=\s*")(.*\.jpg/@@images/)(.*\.jpeg")( .*$)', line)
if find:
result.append(find.group(1)+find.group(2)+'image/preview"'+find.group(4))
else:
result.append(line)
result = '\n'.join(result)
obj.myfield = RichTextValue(result, 'text/html', 'text/x-html-safe', 'utf-8')
obj.reindexObject()
transaction.commit()</pre>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-84436218410020995992016-08-12T16:22:00.001+08:002016-08-13T22:01:35.514+08:00Plone5 Theme Customization<p>Plone5 is released for quite a long time, but recently I finally get a chance to work with its default <a href="http://marrtw.blogspot.tw/2014/03/plone-theme-barceloneta.html">Barceloneta Theme</a>. For Plone5 new comers, be sure to read first the article "<a href="http://datakurre.pandala.org/2015/05/customize-plone-5-default-theme-on-fly.html">Customize Plone 5 Default Theme On the Fly</a>". One small thing about the Barceloneta theme, from the Front Page text, there's a big welcome string, named hero text, later turned into <a href="https://github.com/plone/Products.CMFPlone/issues/974">@@hero view</a> in Plone 5.0.3. So you can reference the following code to highlight some text:</p>
<pre><div class="hero">
<h1>Welcome!</h1>
<p><a class="context" href="http://plone.com" target="_blank">Link</a></p>
</div></pre>
<p>Separated text, say in the end paragraph, with the <code>hero</code> class will display in the same box.</p>
<img src="https://lh3.googleusercontent.com/dIg-12hMCRxe8ZwvCp96c5znuCR1VB887N5TD_jrhEEXa3_f7ecXH6a9a0ZZdyoIE6NrGHjN1OZOF0Axb_RJqJ20JpTpihbglq48_SpEH1MO8udKL37KM7SZPVdrdgp_XURW3kq9Zr6xG3wdPG-LdAIF8l6OrlTduyecDJjJX0ku_7_vhKnCpD6q4foaDUBa4mdIX-copH9wNn7KqREqYff9DaMw3jtNMZvuv7B47r2aN0U6qLKwFG4sW9uke8lmGsqsm88-AmxYWHqptwpIrCcD238hZdShbitouOFt01i-oh8VOgwc9eo8aowwBWvvWM_9txAlRXD9gPspTFBC0YQu633DY2Oy-_TxlN_8JyCGEPuOVFrCtcAzVvFlK1ofiuN7RzQyPTYrcXOIfNoeGrWutw2T2-ynELjk6Hs65uVBIIBi_eBGpBPNbWL-Pr1oAmaJGpaAbR24qKKp-Jb-0nWUM5tnAmE86Y2-x0setEoIRZUulSh2rjg_DBrpIdrDsNOWXBrNLKXEIlsw1CZ_DeahCsK2-GtSBU_SOouPyh_cfPE1dBQL6tp1mw7CPzp0r05e946nCVWODI4175QCKFqnPvmVg8o=w357-h376-no" />
<p>Barceloneta uses LESS as a pre-processor to generate the final CSS files. In addition, its LESS/CSS is not registered on the registry, so you need to <a href="https://github.com/plone/plonetheme.barceloneta/blob/master/HOWTO_DEVELOP.rst">compile it with gruntfile</a>.</p>
<p>Then, if you want to develop your custom theme in the filesystem, take a look at <a href="http://github.com/collective/plonetheme.persona">plonetheme.persona</a>. Persona Theme is good for blog-style site, not suitable for portal, anyway it is a good start to learn about customization based on Barceloneta. Here is the development buildout log:</p>
<pre>$ bin/buildout -c develop.cfg
mr.developer: Queued 'plonetheme.persona' for checkout.
mr.developer: Filesystem package 'plonetheme.persona' doesn't need a checkout.
Develop: '/home/marr/plone505/zinstance/src/plonetheme.persona'
Uninstalling zopepy.
Uninstalling instance.
Installing _mr.developer.
Generated script '/home/marr/plone505/zinstance/bin/develop'.
Installing instance.
Getting distribution for 'mockup-highlightjs'.
Got mockup-highlightjs 1.0.0a2.
Getting distribution for 'plone.app.themingplugins'.
Got plone.app.themingplugins 1.0.
Getting distribution for 'z3c.jbot'.
Got z3c.jbot 0.7.2.
Generated script '/home/marr/plone505/zinstance/bin/instance'.
Generated interpreter '/home/marr/plone505/zinstance/parts/instance/bin/interpreter'.
Generated script '/home/marr/plone505/zinstance/bin/pilprint.py'.
Generated script '/home/marr/plone505/zinstance/bin/pilconvert.py'.
Generated script '/home/marr/plone505/zinstance/bin/enhancer.py'.
Generated script '/home/marr/plone505/zinstance/bin/thresholder.py'.
Generated script '/home/marr/plone505/zinstance/bin/viewer.py'.
Generated script '/home/marr/plone505/zinstance/bin/explode.py'.
Generated script '/home/marr/plone505/zinstance/bin/player.py'.
Generated script '/home/marr/plone505/zinstance/bin/pildriver.py'.
Generated script '/home/marr/plone505/zinstance/bin/pilfile.py'.
Generated script '/home/marr/plone505/zinstance/bin/painter.py'.
Generated script '/home/marr/plone505/zinstance/bin/createfontdatachunk.py'.
Generated script '/home/marr/plone505/zinstance/bin/gifmaker.py'.
Generated script '/home/marr/plone505/zinstance/bin/pilfont.py'.
Updating repozo.
Updating backup.
Installing zopepy.
Generated interpreter '/home/marr/plone505/zinstance/bin/zopepy'.
Updating unifiedinstaller.
Installing test.
Generated script '/home/marr/plone505/zinstance/bin/test'.
Installing diazotools.
Generated script '/home/marr/plone505/zinstance/bin/diazocompiler'.
Generated script '/home/marr/plone505/zinstance/bin/diazorun'.
Generated script '/home/marr/plone505/zinstance/bin/diazopreprocessor'.
Installing checkdocs.
Installing mrbob.
Getting distribution for 'MarkupSafe==0.23'.
Got MarkupSafe 0.23.
Generated script '/home/marr/plone505/zinstance/bin/mrbob'.
Installing releaser.
Generated script '/home/marr/plone505/zinstance/bin/fullrelease'.
Generated script '/home/marr/plone505/zinstance/bin/postrelease'.
Generated script '/home/marr/plone505/zinstance/bin/lasttagdiff'.
Generated script '/home/marr/plone505/zinstance/bin/addchangelogentry'.
Generated script '/home/marr/plone505/zinstance/bin/bumpversion'.
Generated script '/home/marr/plone505/zinstance/bin/prerelease'.
Generated script '/home/marr/plone505/zinstance/bin/release'.
Generated script '/home/marr/plone505/zinstance/bin/longtest'.
Generated script '/home/marr/plone505/zinstance/bin/lasttaglog'.
Generated script '/home/marr/plone505/zinstance/bin/pocompile'.
Versions had to be automatically picked.
The following part definition lists the versions picked:
[versions]
# Required by:
# plonetheme.persona==1.0a2.dev0
mockup-highlightjs = 1.0.0a2
# Required by:
# plonetheme.persona==1.0a2.dev0
plone.app.themingplugins = 1.0
# Required by:
# plone.app.themingplugins==1.0
z3c.jbot = 0.7.2</pre>
<p>Look into profiles/default/metadata.xml you will see <dependency>profile-plonetheme.barceloneta:registerless</dependency></p>
<img src="https://lh3.googleusercontent.com/D6v7jBbWDfJ-HICVYb53jj9UiQScZxpABd8sVyEJS4Dql1sl57eGMorMyebo1ufo-nj2KKl1yDFoo8L1gyjcZgunCNW2BLmKlrQ8W4hu9GFz6SLCNrY17Wak5nLsSKS3g1Zwd1S-VZY7pSf4a2uM3rhl3-cqBr4xVZ54OSZsopU59aSvUKiu-M_zebvEC6htRkY9KrFB43WiOmwm7sRPm0dq83j6l0VJi662Cr6fGkZ9zWPB13Nqyro0g6dlqyy5DJR8j-RXwOlb73w7PzmrH9Q9dAtXOWcQgbE6D_VHji52IYBuHUgkCwTbcUQ8j5WVuYLvVMyCiFbRh3JbbQiivbD1Z-A-FdIln_0BB4Lx42xjSPITnnefS6OC_cQMJu6TsBeG2zx51ajslm0z2PPpowL_KAHbOxiyK7Ruwh9N-KmjnZdDLdRN5TBQwdsrd1lGbvt8vcEtlYggTqFohuOKxzUFhyntG59zPBHGvfPfycPGWXrjysnbMX2NBjCdaBPGZeyp3tmgtNzo88mbYfrOV9NI6JisdSABNw7MTy7i2qFyk09h_2r9PZdoO3piS1lYmoPTki9PXU2fRv-MPjpNSGbRNLl9lo4=w750-no" />marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-83848902785217375812016-07-14T13:48:00.000+08:002016-07-14T13:48:33.183+08:00plone.app.event tzinfo<p>如果你使用新版 Plone 5.x 或 Plone 4.3.x 加上 plone.app.contenttypes 昇級,應該就會遇到 plone.app.event 帶來的 tzinfo 時區衝擊。假設 item = app.mysite.events['20160701'] 那我們可以用 item.creation_date 讀取建立時間,類似 DateTime('2016/07/01 00:30:23.674693 UTC') 這樣的格式,這表示它還是使用傳統的時間格式,試 item.start 和 item.end 的話,會發現類似 datetime.datetime(2016, 3, 23, 16, 0, tzinfo=<UTC>) 的格式。</p>
<p>文件 <a href="http://docs.plone.org/develop/plone/misc/datetime.html">Zope DateTime</a> 有基本的說明,可惜並沒有幫到忙,我想要把上述時間轉成 GMT+8 的格式,這會影響到「三月23日」和「三月24日」的差別。找到 <a href="http://www.saltycrane.com/blog/2009/05/converting-time-zones-datetime-objects-python">Converting Time Zones for datetime Ojbects</a> 讓事情有了進展:</p>
<pre>fmt = "%Y-%m-%d"
item.start.strftime(fmt)
from pytz import timezone
item.start.astimezone(timezone('Asia/Taipei')
datetime.datetime(2016, 3, 24, 0, 0, tzinfo=<DstTzInfo 'Asia/Taipei' CST+8:00:00 STD>)</pre>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-12776788569078098532016-06-13T10:33:00.004+08:002016-06-13T10:58:21.452+08:00OpenGeo Suite<p>Boundless Exchange 是 Boundless GIS Platform 的一部份,它的功能看來是對應了 GeoNode,而 GeoNode 文件表示它是個 GIS CMS,能夠用來新增 Layer, Map, Document (例如 Excel, PPT, PDF 等),也有群組和簡易權限控制,加入我們的歷史圖資或 Shape File 內容,都可以做到,但我沒發現能直接編輯 HTML 或調整呈現的功能。</p>
<p>整體來說,Boundless Exchange 是編輯 GIS 素材最好的 Open Source 系統環境,算是提供地圖資訊的後台便利環境,但直接在上面「說故事」似乎還不適合,短時間內應該要搭配其他能夠編輯 HTML 的前台環境。如果搭配 <a href="https://drive.google.com/file/d/0B58xosQrjSXHMnRkODV3OTY4aDQ/view">LocalWiki</a> 的話,方便共同編輯,但呈現形式要調整後,才容易具備彈性。</p>
<p><a href="https://drive.google.com/file/d/0B58xosQrjSXHakJpVUk0dmh4djg/view?usp=sharing">GeoNode fig1</a> <a href="https://drive.google.com/file/d/0B58xosQrjSXHYTVUQ3NoVndqMDg/view">GeoNode fig2</a> <a href="https://drive.google.com/file/d/0B58xosQrjSXHcHdqZTBLcmEzRFk/view">GeoServer fig1</a> <a href="https://drive.google.com/file/d/0B58xosQrjSXHbW03aDNxVG1qYnc/view">GeoServer fig2</a></p>
<p>就<a href="http://docs.geonode.org/en/master/tutorials/overview_and_ref/reference_doc/components.html">擴充開發的角度</a>來看,Python 寫成的元件 (像 Django, pycsw) 偏向前端,以 Java 寫成 (例如 GeoServer) 是後端核心,在調整顯示的情境下,主要應是修改 JavaScript 和 Python 的前端元件部份。</p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-67559763816334250102016-04-28T23:05:00.001+08:002016-04-29T11:13:13.583+08:00在地深耕, 迎向國際<p><a href="http://tw.pycon.org/2016">2016 台灣 Python 年會</a> (PyCon Taiwan) 六月 3日 到 5日 在台北南港中研院 舉辦三天,總數超過 40場演講,主題涵蓋資料科學、人工智慧、金融科技、網站開發技術、雲端應用、青少年程式教育,會前搭配專案實作 (Sprint) 和專業課程 (Tutorial) 活動,會後在政治大學搭配新手村 (PyDay) 活動,更多資訊請參考 <a href="http://tw.pycon.org/2016/events/overview/">http://tw.pycon.org/2016/events/overview/</a> 介紹。</p>
<p>五位主題講者,包含網站技術專家、微軟 Python 工程師、<a href="https://www.facebook.com/pycontw/posts/946318345487008">迪士尼動畫工程師</a>,還有<a href="https://www.facebook.com/pycontw/posts/949944361791073">黃敬群和唐鳳</a>,兩位出身台灣、自學成才、享譽國際的自由軟體資深貢獻者。</p>
<p>本地出身的主題講者,佔了五分之二,這樣安排,是為了體現 PyCon Taiwan 的願景目標: 發展 Python 技術,提昇社群專業。簡單地說,我們要在台灣搞出一系列一流的產品服務,不限於 PyCon 或 Python,但我們選擇 Python 為核心,從年會出發累積。這個願景方向,我們努力了五年,交出讓自己驕傲的成績單,但還有很大的天地等我們去發展和成長。</p>
<p>如果能作夢,我期待成立台灣 Python 基金會,做什麼事呢? 推展青少年教育,讓 Python 成為各行各業的核心技術,社群專案和講者多到滿出來,台灣成為技術重鎮,工作效率提昇系統穩定成長,大家早點下班去做自己覺得有意義的事。如果要有這樣的一天,那麼搞好一個持續成長的 PyCon,也只是個起點罷。人生苦短,你想做的是什麼呢?</p>
<p>提到程式教學,幾場相關的講題摘要如下:</p>
<ul>
<li>主題演講 Jim Huang (jserv) 分享應用 Python 在大學作業系統和編譯器課程的經驗,以及 Python 編譯器與虛擬機器的內部設計。</li>
<li>分享兒童程式教學經驗 Teach Kids to Learn Python: Eric Huang 針對小六到高一設計 Python 入門課程,說明學習 Python 應先具備的能力,入門的九個重點,提供上機練習體驗,最重要的是,如何引發學生學習的動機,培養寫程式的能力和自信心。</li>
<li>Learning the Basics: 來自香港的十一歲少年 Isaac Li (英文演講) 經由小遊戲的設計概念,分享自己學習 Python 的經驗談,用意是激勵更多青少年朋友接觸程式學習。</li>
<li>Coaching Teens to Learn Python: Edward Duh 檢視多種可能適合青少年學習的工具,包括 Raspberry Pi、Minecraft Pi、CheckiO、IPython Notebook 等,並分享教學設計的實務經驗,怎樣讓學習變得有趣。</li>
</ul>
<p>早鳥優惠到五月1日 18:04,還沒<a href="http://tw.pycon.org/2016/registration/ticket-info/">買票</a>的朋友,別錯過囉。</p>
<blockquote>"The past cannot be changed. The future is yet in your power." -- Hugh White</blockquote>
<p>Let's Implement the Future, Together!</p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-47678117154006841682016-04-28T17:21:00.004+08:002016-04-28T17:21:49.933+08:00Get Your PyCon Taiwan 2016 Tickets<table style="width:auto; margin-bottom: 30px"><tr><td><a href="https://picasaweb.google.com/lh/photo/9mtPSXLdnctspA9R8Od-4tMTjNZETYmyPJy0liipFm0?feat=embedwebsite"><img src="https://lh3.googleusercontent.com/-G6ioDk62dJY/VyHNw926p7I/AAAAAAAAERQ/KKzbpn2TnAApLCbhaHyaOBmivMarEP1tQCCo/s640/rule-no1.png" height="410" width="640" /></a></td></tr><tr><td style="font-size:20px; text-align:center">學習程式語言,第一先要入門產生興趣,再培養良好的自學能力。</td></tr></table>
<table style="width:auto; margin-bottom: 30px"><tr><td><a href="https://picasaweb.google.com/lh/photo/56IocbPNqMZkOTIyyGxmVNMTjNZETYmyPJy0liipFm0?feat=embedwebsite"><img src="https://lh3.googleusercontent.com/-Y1UTMeiK9i0/VyHN2yqkqNI/AAAAAAAAERw/DicEapyy0XYmDVNurh3XOwJk4Wb9rUasQCCo/s640/python-good.png" height="433" width="640" /></a></td></tr><tr><td style="font-size:20px; text-align:center">寶寶心裡爽,但寶寶還是要說: Python 的好 妙不可言啊</td></tr></table>
<table style="width:auto; margin-bottom: 30px"><tr><td><a href="https://picasaweb.google.com/lh/photo/CicLXjAiACR4n8yJ5-bEWdMTjNZETYmyPJy0liipFm0?feat=embedwebsite"><img src="https://lh3.googleusercontent.com/-gTsmXAE-Xc8/VyHN-MSi2GI/AAAAAAAAERw/_Hn62Y2LkUU1WTIrmm0nbFG77fqC69yYgCCo/s800/call-buy.png" height="438" width="628" /></a></td></tr><tr><td style="font-size:20px; text-align:center">阿榮啊,放假要記得去買 PyCon Taiwan 門票,順便再捐 500 給 OCF 基金會。</td></tr></table>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-89017903979589599532015-11-17T14:14:00.002+08:002015-12-23T17:35:20.828+08:00Omeka Notes<p><a href="http://openfoundry.blogspot.tw/2015/08/omeka-ubuntu-installation.html">安裝 Omeka 2.3.x</a> 之後,有幾個常見問題,依自身實務的需求優先順序來說明:</p>
<p>* Item 只能對應一個 Collection 不能對應多個。所謂的 <a href="https://omeka.org/codex/Plugins/CollectionTree_2.0">Collection Tree</a> 通常幫不上任何忙。</p>
<p>* Theme 客製化機制建議先參考這一<a href="http://interactivemechanics.com/news/2014/09/basics-building-omeka-themes/">系列說明</a>,Common Layout 無法依 Item 或 FrontPage 來客製,例如 <a href="http://omeka.org/forums/topic/where-to-put-disqus-or-intense-debate-embed-code">Disqus Embed Code 無法依 Item (or Item Type) 來顯示</a>。</p>
<p>* <a href="https://omeka.org/codex/Managing_Navigation_2.0">Navigation 管理方式</a>只有一招,每個 Tab 都要指定 Link URL。</p>
<p>* Item 與 Collection 不能容易地自訂網址。</p>
<p>* 描述欄位的<a href="http://blog.longwin.com.tw/2006/02/php_mb_strimwidth_function">中文斷字</a>預設無法正常顯示,至少要修改下列檔案:</p>
<ul><li>application/views/scripts/items/single.php</li><li>application/views/scripts/collections/single.php</li><li>themes/.../collections/show.php</li>
<li>application/views/scripts/items/browse.php</li></ul>
<p>* 地圖座標搭配 CSV Import 時,無法批次處理。</p>
<p>* <a href="http://omeka.org/forums/topic/make-sub-items-collapsed-by-default-in-exhibit-nav#post-108095">Exhibit 的 SubItem Navigation 不能客製化</a>。</p>
<p>* <a href="http://omeka.org/forums/topic/wanting-to-create-a-slide-show-getting-nowhere#post-101390">Slide Show 模組整合選項有限制</a>,較可行的是像 CSSlider。</p>
<p>* <a href="https://groups.google.com/forum/#!topic/omeka-dev/Hyzv_Thmg6E">利用 GetText 建立</a>翻譯用的 <a href="https://github.com/omeka/Omeka/tree/master/application/languages">pot po 檔</a>,但沒有支援 Multi Lingual 機制。測試用 msgfmt -o 產生的 mo 並沒有成功生效。</p>
<p>* <a href="http://omeka.org/forums/topic/display-total-items-in-omeka-20">留意 Version One vs Two 的差異</a>。</p>
<p>* <a href="http://omeka.org/forums/topic/shortcodes-and-item-specific-metadata">Short Code 範例</a></p>
<p>* Collection <a href="http://omeka.org/forums/topic/sort-items-chronologically#post-1663">排序調整</a> <a href="http://omeka.org/forums/topic/display-total-number-of-items-for-each-collection-on-index">數量統計</a> 的範例</p>
<p>試用 Plugin 的心得記錄:</p>
<p>* <a href="http://omeka.org/add-ons/plugins/youtube-import/">Youtube</a> 會新增一個匯入介面,輸入個別的影片網址,會自動填寫欄位資料。</p>
<p>* 安裝 GeoLocation Plugin 後,搜尋表單會增加地理相關搜尋欄位,但測試會造成錯誤,要從 application/views/scripts/items/search-form.php 移除 php fire_plugin_hook() 來停用搜尋欄位。</p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-6921002941147269612015-10-26T11:21:00.000+08:002015-10-26T11:41:24.663+08:00Python Course at NanGang High School<p>Almost 10 years from now ... http://www.openfoundry.org/en/component/content/article/580-ossf-</p>
<p>Slides at http://www.openfoundry.org/download/cat_view/212</p>
<img src="https://lh3.googleusercontent.com/-NCcWlQutoso/Vi2WpT38BSI/AAAAAAAAEDI/ciZdU3aRp1g/s512-Ic42/DSC06415.png" />
<img src="https://lh3.googleusercontent.com/-GdyWFxcYCdQ/Vi2WxGar3gI/AAAAAAAAEDQ/T-5M7IdqE9Y/s512-Ic42/j501846.png" />
<img src="https://lh3.googleusercontent.com/-i2cZLEvxLek/Vi2W1l5fFzI/AAAAAAAAEDY/0POx2gcCL8M/s512-Ic42/kira.png" />
<img src="https://lh3.googleusercontent.com/-LuFCwYLrvfw/Vi2W8ZbXr8I/AAAAAAAAEDg/yPA0A5DN9JU/s512-Ic42/j790213.png" />
<img src="https://lh3.googleusercontent.com/-4vr2uMJUVp8/Vi2W_bAYCMI/AAAAAAAAEDo/QEOC54mBNEs/s512-Ic42/linc081320.png" />
<img src="https://lh3.googleusercontent.com/-FWP8pald63M/Vi2XCu5qeII/AAAAAAAAEDw/CvQsYvYzS04/s512-Ic42/macos.png" />
<img src="https://lh3.googleusercontent.com/-sQxxbkNcYyE/Vi2XFJDcv6I/AAAAAAAAED4/51nxOPmPVNk/s512-Ic42/mato.png" />
<img src="https://lh3.googleusercontent.com/-0vks8n-8rqY/Vi2XHrV21EI/AAAAAAAAEEA/VNt5J2gL0pc/s512-Ic42/shan.png" />
<img src="https://lh3.googleusercontent.com/-XoVccjIl5cE/Vi2XKGDQX3I/AAAAAAAAEEI/iYQ_8U2cDAs/s512-Ic42/steven.png" />
<img src="https://lh3.googleusercontent.com/-cNvpNfoEEDE/Vi2XNHDbKnI/AAAAAAAAEEQ/w6XNypaYv6Y/s512-Ic42/tommy.png" />
<img src="https://lh3.googleusercontent.com/-p_waoMnzjH0/Vi2XPOrewmI/AAAAAAAAEEY/zvztRIcv664/s512-Ic42/tony.png" />
<img src="https://lh3.googleusercontent.com/-ixLmPcjFXbE/Vi2XS4gZxrI/AAAAAAAAEEg/0C1Ttzj4r6c/s512-Ic42/xcurdb.png" />marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-2419612994526165932015-07-28T22:03:00.002+08:002015-10-02T15:41:14.103+08:00Custom JavaScript Pattern Settings in Plone5<p>Plone 5 beta 3 is now released. <a href="http://contentgardening.com/en/articles/how-I-follow-plone5-development">Building from the source code</a> is easier, compared to <a href="http://marrtw.blogspot.tw/2013/10/building-plone-latest.html">how we did it before</a>.</p>
<pre>$ virtualenv myenv
$ git clone -b 5.0 https://github.com/plone/buildout.coredev ./plone50dev
$ cd plone50dev
$ ../myenv/bin/python bootstrap.py
$ bin/buildout</pre>
<p>Playing with Mockup is fun in Plone 5. See <a href="http://www.nathanvangheem.com/news/customizing-javascript-pattern-options-in-plone-5">Customizing JavaScript Pattern Settings in Plone 5</a> to get started.</p>
<p>One way to work with your project: checkout the codes in src folder, edit core.cfg to modify eggs and develop under [buildout] section.</p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-86953883257448900962015-06-26T16:40:00.001+08:002015-06-26T17:29:53.028+08:00QAs for Python Beginners<p>學習 Python 前,你可能會遇到下列的疑問,對於這些問題,你心裡的答案是什麼呢?</p>
<p>這裡未必提供完整精準的解析,但希望有助於帶你看到學習程式語言的新觀點。</p>
<p><b>要懂物件導向才能學習 Python 嗎?</b></p>
<p>在 Python 中,每個東西都是物件,但,不代表你必須使用物件導向作為 Python 的主要典範,舉例來說,有人仿照 Functional Programming 典範來使用 Python。不懂物件導向觀念,不致於成為學習的阻礙,當然,具備物件導向的觀念,有助於進階議題的學習。</p>
<p><b>Python 是 Script 語言,執行效率一定比較慢囉?</b></p>
<p>善用內建函式和內建型別的情況下,Python 的效能並沒有比編譯式語言來得差。常見的建議是,等到程式架構穩定之後,再決定是否要處理效能問題,以及採取怎樣的處理方式。參考下列文件:</p>
<ul><li>http://www.python.org/doc/essays/comparisons/</li>
<li>http://www.infoworld.com/article/2619428/python/van-rossum--python-is-not-too-slow.html</li>
<li>http://www.monitis.com/blog/2012/02/13/python-performance-tips-part-1</li>
</ul>
<p><b>Python 的中文書籍很少,需要具備足夠英文程度才能學習嗎?</b></p>
<p>編寫品質良好的中文程式書籍,是極度吃力不討好的工作,結果就是,我們在市面上很難找到好的中文書。英文書的種類和數量,相對就多些。
想要自學的朋友,先選擇好的英文書和線上文件外,聰明的作法,就是參加同好聚會,線上和實體課程。</p>
<p><b>需要選好 IDE 才能開始 Python 編程嗎?</b></p>
<p>Python 世界裡存在許多 IDE 編輯器,免費或付費版本都有,各有愛用者。不少人使用 Vim 或 Sublime Text 就覺得夠用,所以,沒有 IDE 無法編程,對 Python 肯定是不成立的。</p>
<p><b>Python 的變數不用事先宣告型態,容易造成程式產生難以預期的錯誤或漏洞?</b></p>
<p>Python 是 Dynamic Typing 語言,使用變數時,不像 C 或 Java 需要事先宣告資料型態。Python 雖然有 <a href="http://stackoverflow.com/questions/1641219/does-python-have-private-variables-in-classes">Private 變數</a>,但不像一般程式語言那樣具有強制力。通常會利用 Testing 來降低資料型態不明可能造成的問題,另一方面,也利用 Duck Typing 特性來避免資料型態檢查的需要。</p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-77892358159366167642015-06-25T21:37:00.000+08:002015-06-25T21:54:02.079+08:00Anaconda on Windows<iframe src="https://onedrive.live.com/embed?cid=2E2086F1483EEB8F&resid=2E2086F1483EEB8F%21108&authkey=AC_7pOmNBfz4gDg" width="320" height="247" frameborder="0" scrolling="no"></iframe>
<iframe src="https://onedrive.live.com/embed?cid=2E2086F1483EEB8F&resid=2E2086F1483EEB8F%21107&authkey=AM4yS3HBARCCwCs" width="320" height="247" frameborder="0" scrolling="no"></iframe>
<iframe src="https://onedrive.live.com/embed?cid=2E2086F1483EEB8F&resid=2E2086F1483EEB8F%21107&authkey=AM4yS3HBARCCwCs" width="320" height="247" frameborder="0" scrolling="no"></iframe>
<iframe src="https://onedrive.live.com/embed?cid=2E2086F1483EEB8F&resid=2E2086F1483EEB8F%21109&authkey=AGDTP_K4wfoB1So" width="320" height="247" frameborder="0" scrolling="no"></iframe>
<iframe src="https://onedrive.live.com/embed?cid=2E2086F1483EEB8F&resid=2E2086F1483EEB8F%21110&authkey=AJ5Kx-idfcjQqSA" width="320" height="247" frameborder="0" scrolling="no"></iframe>
<iframe src="https://onedrive.live.com/embed?cid=2E2086F1483EEB8F&resid=2E2086F1483EEB8F%21111&authkey=AKexCBiqEpQ7MTw" width="320" height="247" frameborder="0" scrolling="no"></iframe>
<iframe src="https://onedrive.live.com/embed?cid=2E2086F1483EEB8F&resid=2E2086F1483EEB8F%21111&authkey=AKexCBiqEpQ7MTw" width="320" height="247" frameborder="0" scrolling="no"></iframe>
<iframe src="https://onedrive.live.com/embed?cid=2E2086F1483EEB8F&resid=2E2086F1483EEB8F%21112&authkey=AM2ZShAfp2ENsK4" width="320" height="209" frameborder="0" scrolling="no"></iframe>
<iframe src="https://onedrive.live.com/embed?cid=2E2086F1483EEB8F&resid=2E2086F1483EEB8F%21113&authkey=AIpa3389muQLj2o" width="320" height="172" frameborder="0" scrolling="no"></iframe>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-6694659183937561932015-05-25T15:49:00.004+08:002015-05-25T15:49:58.658+08:00Learning Programming Fast<p>絕不貪快,按部就班,是學好程式的不二法門,除此之外,還是有五個步驟,有助加速學習:</p>
<ol>
<li>先讀範例程式,再讀說明文字。</li>
<li>打一遍範例程式,執行並測試。</li>
<li>找個實例練習自己寫程式。</li>
<li>學習使用除錯器。</li>
<li>聰明發問,獲得更多角度的解說。</li>
</ol>
<p>以上我稱之為「程式學習快速秘笈」,<a href="http://www.improgrammer.net/learning-programming-fast-in-just-5-steps/">原文在這裡</a>。</p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-91296652175274262092015-05-22T11:49:00.000+08:002015-05-22T11:49:13.630+08:00After-School Class<p>小孩的媽,最近開始比較住家附近的安親班,用心程度,堪比孟母三遷。</p>
<p>藉由這些親身接觸的機會,我們才體會現代孟母面對怎樣的挑戰。</p>
<p>首先,安親班數量之多,約是便利商店三倍;其次,從業者專注特色,幾近苛求。</p>
<p>有哪些特色呢? 九成會強調純美語、或雙語教學,如果之前沒有足夠的美語根基,要嘛入班前加強訓練,跟上進度,要嘛就不必進去啦,意思是不要拉下既有班級的素質。至於沒有美語課程的安親班,數量雖少,但氣勢也不輸人,強調「省下來」的時間,會加強學生的在校功課,還有戶外運動。</p>
<p>有一家強調網站軟體,小孩回家可以線上複習,「那麼,該怎樣知道小孩有沒有乖乖複習呢?」「我們有會員系統,可以知道誰有沒有登入看影片。」我腦袋浮出的畫面是,哪一天,小朋友們都會安裝好自動登入的外掛程式吧。</p>
<p>總歸一句話,別讓孩子輸在起跑點。但,我依舊納悶,目標在哪個方向都不知道,起跑再早有什麼意義呢?</p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-35868416092288108052015-02-09T15:40:00.001+08:002015-02-09T15:43:16.832+08:00Plone Widgets<img src="https://41.media.tumblr.com/tumblr_m2k41b1XrF1qeh6kio1_500.jpg" /><p>Shelagh Delaney on the cover of Encore, source: <a href="http://jadorepop.tumblr.com/">http://jadorepop.rumblr.com/</a></p>
<p>Plone 5 使用 Mockup 做為前端函式庫,目的是讓 Plone 的 Javascript 開發更容易與外界成果結合,像 plone.app.widgets 就是範例成果,它可以取代舊的 Widget 程式,從技術的角度來看,代表我們不必再依賴 z3c.form 來建立 Widget 程式碼。截圖畫面和相關細節,可參考<a href="http://www.slideshare.net/witekdev/plone-mockup-modernising-plone-frontend-development">簡報介紹</a>。</p>
<p>如果有任何原因,讓你無法直接使用 Plone 5 環境,從 Plone 4.3.4 Installer 起頭,也能方便地啟用 plone.app.widgets,我的方法和步驟如下:</p>
<pre>$ vi develop.cfg
[sources]
plone.app.event = git git@github.com:plone/plone.app.event.git branch=1.2.x
plone.app.contenttypes = git git@github.com:plone/plone.app.contenttypes.git branch=1.1.x
[buildout]
eggs +=
plone.app.widgets [dexterity]
plone.app.contenttypes
zcml +=
plone.app.widgets
$ vi versions.cfg
plone.app.jquery = 1.8.3
$ bin/buildout -c develop.cfg
# will stop by the error: There is a version conflict. We already have: plone.app.event 1.1.4
$ vi src/plone.app.contenttypes/setup.py
'plone.app.event [dexterity]' # remove <1.1.999</pre>
<p>上述過程適用於全新站台的建立,如果舊站昇級的話,可能會遇到 Tags 欄位未被昇級的狀況。</p>
<img src="https://lh6.googleusercontent.com/-562OXXO_3x4/VNhkDpXSTGI/AAAAAAAADvA/U-HvKJG6nvc/w600-no/widgets.png" />marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-25662994401742307152014-12-26T12:04:00.000+08:002014-12-26T12:48:17.071+08:00Chinese Language Formula<p>中文在數位世界裡,理想上的處理方式,認真探討的人很少,實作的累積速度也慢,不過,這份資源值得參考: <a href="http://chineselanguageformula.sourceforge.net/">http://chineselanguageformula.sourceforge.net/</a></p>
<p>中文語言方程,以構字式為基礎,針對所有的 ISO 639-3 及民族語,採取語言學的正規方法,進行統一處理。目前多組相關的程式碼公開釋出後,原作者想要找人接手維護。</p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-87946926086146193372014-08-14T01:33:00.002+08:002014-08-14T21:22:53.496+08:00Diazo Beginner Steps<p>累積 <a href="http://marrtw.blogspot.tw/search?q=diazo">Diazo 的歷史和原理</a>後,最近終於有個小案子能具體實戰。值得注意的是,套用 Diazo 時,並沒有存在特定的標準解法,需要搭配情境和資源現況,再決定從 Theme 或 Content 或 Rule 找到最容易下手的平衡點。</p>
<p>Theme 原始檔是從 ThemeForest 購買,樣版大致分成「首頁」「列表」「個別頁面」三大類,對初學者容易上手的步驟,是先修改首頁 HTML 符合自己的需要,再編寫 Rule 套用首頁的 Theme 和 Content,接著再逐步納入列表和個別頁面的樣版。編寫 Rule 的過程中,需要仔細比對 Content 和 Theme 的 HTML Tag 或是 XPath,為了方便比對,開啟兩個 browser 畫面,利用 Alt + Tab 切換。有個小撇步,在網址後面加上 ?diazo.off=1 就能暫時取消 Diazo 的效果,但在開發階段,全站式的取消效果會更方便。</p>
<img src="https://lh6.googleusercontent.com/-C8ZNg7sAWjs/U-ukbeUd3dI/AAAAAAAADhU/5EKAoEdqcII/w463-h567-no/01.png" />
<p>以 http://diazo.mysite.com/ 為例,如果 Plone Site 在 http://168.168.168.168:8080/drchen 執行,可以在 http://168.168.168.168:8080/drchen/@@theming-controlpanel 指定 168.168.168.168 是「不套用佈景主題的網址」,這樣就可以在 http://diazo.mysite.com/ 顯示 Rule 生效後的結果,在 http://168.168.168.168:8080/drchen 顯示 Untheme Content 的結果。</p>
<p>網址的對應,是 Diazo Rule 最常見的設定工作之一。以下列 Theme 程式碼為例:</p>
<pre><a href="index.html">
<img src="img/logo.png" />
MySite Home</a></pre>
<p>它會被預設轉換成:</p>
<pre><a href="/++theme++drchen.theme/index.html">
<img src="/++theme++drchen.theme/img/logo.png" />
MySite Home</a></pre>
<p>對於圖檔而言,這樣的網址轉換並沒有造成困擾,但是 A Tag 就得額外處理。最直覺的方式,是讀取 Content 實際的 href 屬性值來取代,有趣的是,雖然是要「取代」 Link 值,但 Rule 語法要用 <copy /> 並指定 Attribute,用 XPath 選取 Node 的範例長得像這樣:</p>
<pre><copy attributes="href"
theme="/html/body/div[2]/div[1]/div/div[1]/a"
content="//*[@id='portal-logo']" /></pre>
<p>我的理解是,想要取代 Node 時,才用 <replace />。接著,我們以 Global Section 為例,介紹幾個相關的對應情境。</p>
<img src="https://lh5.googleusercontent.com/-QhgQ2hN1jnM/U-wjddoONQI/AAAAAAAADiI/B9Jacvy3Vso/w764-h300-no/02.png" />
<p>想要逐一取代 Global Section 的 A Tag,我們可以仿照上述技巧,透過下列的範例語法來達成:</p>
<pre><replace theme="/html/body/div[2]/div[1]/div/ul/li[1]/a"
content="//*[@id='portaltab-index_html']/a" /></pre>
<p>不過,在這個例子裡,我們應該要連帶處理 <li class="selected"> 的部份,僅是取代 A Tag 的結果並未滿足實際的需要。那麼,取代整個 <ul /> 如何? 事實上,我們想留下 Theme 的 <ul> 但取代掉剩下的 <li /> 部份。幸好,有個 -children 語法能夠漂亮地處理這種需求:</p>
<pre><replace theme-children="/html/body/div[2]/div[1]/div/ul"
content-children="//*[@id='portal-globalnav']" /></pre>
<p>我有成功試過其他方法,是先修改 Global Section Viewlet 的 Template 內容,在 <ul> 加上 CSS Class 屬性值,再用 <replace /> 完成取代。相較之下,簡潔的 -children 語法就像一刀斃命。</p>
<p>有時候會遇到一個 Node 裡,同時有數個 A Tag 要指向相關的網址,參考下列的 Theme 原始碼:</p>
<pre><li>
<h2>
<a href="#" title="">
看診科別項目
</a>
</h2>
<div class="news clearfix">
<p class="text">
小兒科、過敏氣喘、耳鼻喉治療<br>
內科、慢性病處方簽<br>
成人、小兒感冒 等
</p>
<a href="#" title="">更多說明</a>
</div>
</li></pre>
<p>利用 //a 的 XPath 語法,可以指定 Node 裡的所有 A Tag,參考下列的 Rule 範例:</p>
<pre><copy attributes="href"
theme="/html/body/div[2]/div[2]/ul/li[1]//a"
content="//*[@id='portletwrapper-ID']/dl/dt/span[2]/a" /></pre>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com1tag:blogger.com,1999:blog-318830256542227528.post-16242092842923477822014-07-30T16:49:00.002+08:002014-07-31T11:04:39.761+08:00Collection Group By View<p>A <b>Collection</b> in Plone works much like a report or query does in a database. Based on a set of <b>Criteria</b> such as: content types, dates, or keywords, you can search items and display them in a variety of dynamic ways. By default, there are Standard View, Summary View, Full View, Tabular View and Thumbnail View. What I need is to add an Aggregate View (like Group By). Here is how:</p>
<p>First, create a view.py file in the browser folder, where you define the View class. In my case, the results need to be grouped by category field values. Now I get a dictionary like {'category1': [<plone.app.contentlisting.catalog.CatalogContentListingObject instance at /mysite/myfolder/101-c-1>, <plone.app.contentlisting.catalog.CatalogContentListingObject instance at /mysite/myfolder/101-c-2>, <plone.app.contentlisting.catalog.CatalogContentListingObject instance at /mysite/myfolder/101-c-3>], 'category2': [...]}. With TAL nested loop in the aggregate_view.pt template, we can display the result. Finally register this browser view.</p>
<p>Note that this tip might suit only for collections of limited items. There should be much room for performance improvement. For those who are interested in the details how Collection works, see reference at <a href="https://github.com/plone/plone.app.contenttypes/blob/master/plone/app/contenttypes/behaviors/collection.py">plone.app.contenttypes/behaviors/collection.py</a></p>
<script src="https://gist.github.com/l34marr/48ed36a8902fe8f6cc23.js"></script>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-57918160353622778182014-06-25T17:39:00.002+08:002014-06-25T20:34:54.155+08:00Install Plone on Codio.com<p>This is a follow-up for <a href="http://blog.dbain.com/2014/04/install-plone-in-under-5-minutes-on.html">Install Plone in under 5 minutes on Codio.com</a> by David Bain, except Plone 4.3.3 standalone installation is used here.</p>
<p><a href="http://codio.com/">Codio.com</a> 提供線上開發環境,透過瀏覽器就能操作 Linux 系統,效能相當不錯。</p>
<p>臨時需要乾淨的開發或測試環境嗎? 可試看看 Codio 是否滿足需求。已知沒有 sudo 權限,透過 <a href="https://codio.com/s/docs/boxes/box-parts/">Box Parts</a> 可以擴充程式語言、資料庫、函式庫等功能,例如 <a href="https://codio.com/s/docs/specifics/dropbox/">dropbox</a> 就有支援,在持續改進的情況下,說不定教學環境也可採用它。</p>
<p>最簡單的測試方式,是建立一個 Empty Project 的範本。</p>
<img src="https://lh6.googleusercontent.com/-RoUw-T4_VjU/U6qVf5rB-hI/AAAAAAAADVU/VOPfFLow3cA/w932-h567-no/01-create-project.png" width="90%" />
<p>再從 Tools 選單點選 Terminal 來打開命令介面。</p>
<img src="https://lh5.googleusercontent.com/-QSWDwoOl6lw/U6qVidkydsI/AAAAAAAADVc/R4vAvIPZgdU/w762-h342-no/02-terminal.png" width="90%" />
<p>想要安裝 Plone 4.3.3 環境? 在 Terminal 裡執行下列指令:</p>
<pre>curl -L http://goo.gl/drKJp8 | bash</pre>
<p>在 Project 選單點選 Box Info 可以查詢服務連線的資訊,存取網址的技巧,可參考 <a href="https://codio.com/s/blog/2014/04/box-access-with-non-standard-ports/">Non-Standard Port 的規則說明</a>。或是查看 <a href="https://codio.com/s/docs/changelog/">ChangeLog</a> 了解最新版的支援狀況。</p>
<p>查詢 <a href="https://github.com/codio/boxparts/tree/master/lib/autoparts/packages">Package</a> 狀況的範例:</p>
<pre>$ parts search python
apache2_mod_wsgi (3.4)
googleappengine (1.9.5)
jython (2.5.3)
pip (1.5.4-2)
pypy (2.2.1)
python2 (2.7.6-2)
python3 (3.4.1)
setuptools (2.2-2)
swig (2.0.11)
virtualenv (1.11.4-2)</pre>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-49519418961074132372014-06-07T08:58:00.001+08:002014-06-11T16:48:36.097+08:00PyCon APAC 2014 Review<p>很多過去的事,原本以為只是生命裡的點,你不知道它們會連成怎樣的線,直到機緣成熟,才得以窺見故事的輪廓。</p>
<p><img src="https://lh3.googleusercontent.com/-Y88M583q5xA/U5JVyogM2-I/AAAAAAAADLg/aG5yeSoE4Iw/w425-h567-no/IMG_2634.JPG" /></p>
<p>第一年辦 PyCon 時,力邀 Drake 參加,那時彼此不認識,為了介紹這是怎樣的活動,一起吃飯聊天,意外發現我們有哪些共同的朋友。今年,Drake 負責 PyCon APAC 2014 贊助工作,貢獻良多。</p>
<p><img src="https://lh3.googleusercontent.com/-tJ5Valxo8U4/U5KX51culMI/AAAAAAAADMY/WDoJoLN7sek/w600-no/PyConf_Preview_Day2-74.jpg" width="95%" />
<p>PyCon Taiwan 之前的社群聚會,最早包括 2004年 Song 籌辦的 PyZope 活動,還記得的人不多,後來 Thinker 號召的 PycTW 形塑定期活動的基礎,特別是 <a href="http://python.org.tw/PycTW2011">2011年</a>,活動當天遇到颱風,會眾展現風雨無阻的意志,讓 Yung-Yu 有信心召喚蟒眾啟動定期的大型研討會。台灣年會規模遞增,算是站穩腳步,今年 Yung-Yu 籌畫了專屬的 SciPy 議程,還有 APAC Community Panel,就算三年前能預見這些事,實際看著它們發生,還是有種超現實的感覺。</p>
<p><img src="https://lh6.googleusercontent.com/-734HJgClLwY/U5JjLpgS2lI/AAAAAAAADL8/EAIYJN2rJbA/w600-no/PyConf_Preview_Day2-153.jpg" width="95%" /></p>
<p>2000年初學 Python,一見鍾情,雖然懂得很少,還是迫不急待在雜誌上撰文介紹。Tim 那時候是讀者,現在結合 Python 技術開公司,今年成為 PyCon APAC 2014 主席。能由 Mosky 獻花慶生,相信 Tim 那一刻已經忘卻籌備的辛勞。</p>
<iframe width="560" height="315" src="//www.youtube.com/embed/4Qvnv5wZIx8" frameborder="0" allowfullscreen></iframe>
<p>1995年 Tom 小學剛畢業,學了 Linux 架 BBS 站,2004年學了 Python,現在已經成為全端工程師,最新目標是投入數位音樂表演,今年的閃電秀裡,Tom 展現了創意實作的成果。</p>
<p><img src="https://lh3.googleusercontent.com/-iDkmm7OOV3g/U5LBMOU_E-I/AAAAAAAADM0/3KKELd6SBjc/w945-h567-no/PyConf_Preview_Day2-159.jpg" width="95%" /></p>
<p>PyCon APAC 2014 亮點太多了 [<a href="http://emptysqua.re/blog/pycon-apac-2014-recap/">1</a>][<a href="http://www.codedata.com.tw/social-coding/python-conference-newbie-ccr/">2</a>][<a href="http://gihyo.jp/news/report/01/pycon-apac2014/0001">3</a>],每年規模成長的情況下,號稱這是史上最棒的年會,殆無疑義。</p>
<p><img src="https://lh4.googleusercontent.com/-Sv9dbS9d0Cc/U5LJURnH3pI/AAAAAAAADNQ/uBgWkQr4BYk/w914-h567-no/PyConf_Preview_Day2-75.jpg" width="95%" /></p>
<p>期待明年更棒的年會之餘,別忘了嚮應 Jessica 的呼籲,來年之內為 Python 社群的成長,做一件新鮮事!</p>
<p><img src="https://lh4.googleusercontent.com/-cOb4ejAJOu8/U5O2fIP-XfI/AAAAAAAADN0/5JrfeQzBC0g/w467-h284-no/r3-sample.png" /></p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-8546268718334831152014-06-06T22:30:00.000+08:002014-06-06T22:52:47.321+08:00Title Customization Based On URLs<p>Plone 網站的 <title /> 內容值,預設是由 Content Title 和 Site Title 合併而成,所以瀏覽首頁時,會看到類似「首頁 -- 我的網站」字樣。我想要把結果改成「我的網站」,方法不止一種,最簡單的方法如下:</p>
<p>到 ZMI portal_view_customization 找到 plone.htmlhead.title,它負責 <title /> 的顯示工作。</p>
<p>定義 is_home 變數,判斷網頁位置是否在首頁。</p>
<pre><tal:block define="state context/@@plone_context_state;
is_home python:state.is_portal_root() and state.is_default_page()">
<title tal:condition="python: not is_home" tal:content="structure view/site_title">Site Title</title>
<title tal:condition="python: is_home" tal:content="string:我的網站">Site Title</title>
</tal:block></pre>
<p>以上方法只需要編輯 template 內容,不必修改檔案系統裡的 view 程式碼。</p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-76127715941026444552014-06-05T10:31:00.000+08:002014-06-05T11:09:40.889+08:00Front Page Editing Made Easy<p>首頁給人的第一印象,很重要,對 Web Master 而言,他們還在意能否輕易地編輯首頁內容。</p>
<p>長久以來,Plone 有很多模組都想處理這個問題,但改善有限,直到 <a href="http://www.slideshare.net/simplesconsultoria/collective-cover">collective.cover</a> 模組問世,才讓人眼睛一亮。有圖有真相? 先看<a href="http://www.youtube.com/watch?v=h_rsSL1e4i4">影片介紹</a>,還有這個範例網站 <a href="http://www.vtv.gob.ve/">http://www.vtv.gob.ve/</a>。</p>
<p>在實作上,它利用 Cover Content Type 來儲存 Layout 資訊,你可以選用預設 Layout,或是透過 Layout tab 自訂細節。每個小格子被稱為 Tile,它可以再被指派 Carousel、Collection、Embed、RichText 等不同功能。</p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-772295867934433202014-05-27T10:20:00.000+08:002014-05-27T10:21:38.285+08:00plone.i18n Configuration<p><img src="https://lh6.googleusercontent.com/-f3lChKmIMWE/Ul4NiqJRevI/AAAAAAAACsU/wrNCRlTe3kA/w833-h533-no/plone-flags.png" width="100%" /></p>
<p>Plone 多國語文支援,相當成熟,想要讓網站支援中英文訊息介面,下列是基本的設定技巧:</p>
<p>在 ZMI 的 portal_languages 先勾選 Allow combined language codes like de_DE or en_UK. 並儲存,再從 Allowd Languages 欄位設定要支援的語系值,例如同時要支援「中文」和「英文」,可以先點選 Chinese (Taiwan) (zh-tw) 項目,再按住 Ctrl 鍵,點選 English (en) 並儲存,再從 Default Language 欄位選擇預設語系,例如 Chinese (Taiwan) 就行。</p>
<p><img src="https://lh6.googleusercontent.com/-estO0muEA9o/UXaHNlZodJI/AAAAAAAAB5o/ayUcqYEshF0/w614-h847-no/plone-i18n-1.png" width="100%" /></p>
<p>Negotiation Scheme 欄位,通常只需要勾選 Use cookie for manual override. 就行。</p>
<p><img src="https://lh5.googleusercontent.com/-DMqpmvPAe4I/UXaHYdQd28I/AAAAAAAAB5o/dTa8urFp6fk/w798-h252-no/plone-i18n-2.png" width="100%" /></p>
<p>預設顯示的訊息文字是「繁體中文(臺灣)」,如果想要修改,可以到 plone.i18n/locales/languages.py 檔案,找到下列的設定內容:</p>
<pre>u'zh-tw' : {u'name' : 'Chinese (Taiwan)',
u'native' : '繁體中文(臺灣)',
u'flag' : u'/++resource++country-flags/tw.gif'},</pre>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0tag:blogger.com,1999:blog-318830256542227528.post-75385789789086863682014-05-25T09:12:00.000+08:002014-05-26T11:09:39.976+08:00Support Our Computer Teachers<p>"What will happen if users can program their own computer?" This is the question asked in <a href="http://www.python.org/doc/essays/cp4e/">Computer Programming for Everybody (CP4E)</a>. Recent developments in computer and communication hardware have given many people access to powerful computers, in the form of desktops, laptops, and mobile devices. It is time to give these users more control over their computers through education and supporting software. If users have a general understanding of computers at the level of software design and implementation, this will cause a massive surge in productivity and creativity, with a far-ranging impact that can barely be anticipated or imagined.</p>
<h3>Why Learning CS?</h3>
<p>Computer science is a foundational field for every 21st century career or field of study. Learning the basics of computer science prepares students for a world that is increasingly dominated by technology. Research shows that students who study computer science also perform better at math. Besides, <a href="http://code.org/stats">computer science is where the jobs are</a>.</p>
<h3>Why Python?</h3>
<p>A key goal for Education is to guide the learners to solve problems and discover solutions. This principal also applies to computer education (CS classes). Every programming language can be used to teach logical thinking. Why and how can Python stand out in such a language war?</p>
<p>Consider this analogy: When running an international conference, a shared language is required. What should it be and how should it be selected? To efficiently communicate in one language, the ideal choice is one with the lowest learning curve and translation cost. Just as how English has become an international language, I believe Python will become the dominant language in the programming world.</p>
<p>No, Python should not be the only language to learn. For a CS professional, it's common to learn various languages, including C and Java. However, Python is still one of the best languages for beginners and those whose limited resources only provide access to one language.</p>
<h3>Give Teachers A Community</h3>
<p>Ok, I want to learn Python, how can I find teachers or trainers? There are more and more online Python courses, just to name some, including <a href="http://www.codecademy.com/tracks/python">Codecademy</a>, <a href="http://www.coursera.org/course/interactivepython">Coursera</a>, <a href="http://www.udacity.com/course/cs101">Udacity</a> and <a href="http://www.learnstreet.com/lessons/study/python">LearnStreet</a>. However, there are few, if any, teachers in schools providing courses based on Python. Besides, CS teachers are usually all alone.</p>
<p>Luckily, <a href="http://www.economist.com/news/international/21601250-global-push-more-computer-science-classrooms-starting-bear-fruit">a global push for more computer science in classrooms is starting to bear fruit</a>. In response to Jessica McKellar's call to action, "<a href="http://marrtw.blogspot.tw/2014/04/the-next-generation-of-programmers.html">Do One Thing Before the next year's PyCon</a>", a group of Taiwan folks <a href="http://www.meetup.com/Taipei-py/events/181244132/">run a meetup</a> to support CS teachers, after the PyCon APAC 2014 Education <a href="http://pycontw.hackpad.com/PyCon-APAC-in-Taiwan-2014-Education-Panel-Track-RRyQFA0g4Iz">Panel</a> and <a href="http://pyconapac2014bof.hackpad.com/Education-BoF-GnujifgUaTe">BoF</a>.</p>
<blockquote>Education is a tree shaking another tree, another cloud to promote a cloud, a soul awakening another soul. -- Karl Theodor Jaspers</blockquote>
<p>Note: thanks to <a href="http://twitter.com/whosbacon">Ken Hu</a>'s help on editing this snippet.</p>marrhttp://www.blogger.com/profile/10683746205883650133noreply@blogger.com0