Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Sphinx customization for OGP support at SphinxCon JP 2018

598 views

Published on

Sphinx拡張を作ってSphinxのHTML出力にOGPタグを追加する話です

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Sphinx customization for OGP support at SphinxCon JP 2018

  1. 1. 1
  2. 2. おまえ誰よ 清水川 貴之 @shimizukawa BeProud, Inc. - connpass, PyQ 一般社団法人PyCon JP - 理事, PyCamp講師 Sphinx - co-maintainer - Sphinx-users.jp 2
  3. 3. で書いた書籍(ここ 年) 3 2017/10/20 Sphinxをはじめよ う 第2版 2018/2/23 独学プログラマー 2018/6/12 Python プロフェッ ショナルプログラミン グ第3版 2018/2/26 エキスパート Pythonプログラミ ング改訂2版 で書いたよ
  4. 4. 今日の シャツ 4
  5. 5. 5
  6. 6. 翻訳 ● 月1回、週末にSphinxのユーザーと、翻訳する人が集まっ て、各自好きなことをやるイベントです。 ● 参加者はだいたい 4~8人 ● sphinx ● documentation ● translation ● 場所: ● 東京の曙橋・市ヶ谷 6 sphinxjp.connpass.com hack-a-thon
  7. 7. ● 2018/12/04(火) 19:30 〜 21:30 ● 場所: 市ヶ谷 アルファーロ(イタリアン) ● SphinxのSlackかGoogle Group (ML)に入ってれば参加 OK 総会 忘年会 7 sphinxjp.connpass.com 総会 / 忘年会
  8. 8. ● 2019/1月?2月? ● 場所: 国立女性教育会館 (埼玉県 嵐山) ● もくもく 開発合宿 8 sphinxjp.connpass.com 合宿
  9. 9. 9
  10. 10. What is Sphinx? Sphinx はドキュメンテーションジェネレーター Sphinxは1つのreSTマークアップのソースから、 複数のファイル形式に出力できます 10 Sphinx reSTreSTreStructuredText (reST) reST Parser HTML Builder ePub Builder LaTeX Builder texlive HTML theme Favorite Editor
  11. 11. 多くのドキュメントがSphinx製 For examples ● Python libraries/tools: Python, Sphinx, Zope, Plone, Pyramid, Django, Flask, SQLAlchemy, Numpy, SciPy, scikit-learn, pandas, fabric, ansible, awscli, … ● Non python libraries/tools: Chef, CakePHP(2.x), MathJax, Selenium, Varnish 11
  12. 12. SPHINX docutils HTML Builder HTML theme (Jinja2) 拡張のメカニズム 12 reST Parser (directive / role) doctree (Intermediate) reSTreST reStructuredText (reST) Sphinx拡張 カスタム記法を追 加 (ディレクティブと ロール) Sphinxのビル ドステージに割 込み And more... 出力形式 の追加 拡張ができることは
  13. 13. 13
  14. 14. ● OGP = Open Graph Protocol. ● OGP はサイトのURLをSNS(Twitter/FB等)に 張ったときに、コンテンツを展開表示する仕組み ● HTMLのメタタグ の一種で、Webページの内容をSNS 上で表示するための情報を提供する 14
  15. 15. <meta property="og:site_name" content="Sphinx-Users.JP"> <meta property="og:title" content="文字数を表示するPageinfoパネル"> <meta property="og:description" content="記事や本などの原稿を..."> <meta property='og:url' content="http://sphinx-users.jp/xxxx.html"> <meta property="og:image" content="http://sphinx-users/xxxx.png"> OGP タグがサイトに含ま れていれば、SNSに画像 やコンテンツのテキストを 表示できる 15 og:image og:description Facebook postingSpec: http://ogp.me/ og:site_name og:title
  16. 16. <meta name="twitter:card" content="summary" /> <meta name="twitter:site" content="@sphinxjp" /> <meta property="og:site_name" content="The site title"> <meta property="og:title" content="Title for displaying on TW/FB"> <meta property="og:description" content="blah blah blah ..."> <meta property='og:url' content="http://sphinx-users.jp/index.html"> <meta property="og:image" content="http://sphinx-users/logo.png"> 16 TwitterもOGPタグに対応 してますが、Twitterの場合 “twitter:card” と “twitter:site” タグも提供 する必要がある og:image og:description Tweet Spec: https://developer.twitter.com/en/docs/tweets/optimize-with-cards/guides/getting-started og:site_name og:title
  17. 17. 17
  18. 18. SphinxはデフォルトではOGPタグに対応してない です。 URLをSNSに貼ったら展開されて欲しい めっちゃ欲しい で Sphinx拡張 作りました :) 18
  19. 19. 拡張 入門 19
  20. 20. Sphinx拡張入門 (1/3) Sphinx拡張のエントリーポイントは、 setup() という関数で す。 今回は `ogtag.py` に `setup` 関数を用意。この関数は、 Sphinx拡張のセットアップをして、メタ情報をリターンします 20 def setup(app): app.add_config_value('og_site_url', None, 'html') app.add_config_value('og_twitter_site', None, 'html') app.connect('html-page-context', html_page_context) return { 'version': '0.1', 'parallel_read_safe': True, 'parallel_write_safe': True, } Spec: http://www.sphinx-doc.org/en/master/extdev/tutorial.html#the-setup-function ogtag.py
  21. 21. Sphinx拡張入門 (2/3) setup() 関数内で app.add_config_value() でSphinxに conf.pyの設定を追加します。 この例では、デフォルト値をNone、値を変えたときは ‘html’ 出 力の場合はフルリビルドするように指定しています。 21 def setup(app): app.add_config_value('og_site_url', None, 'html') app.add_config_value('og_twitter_site', None, 'html') app.connect('html-page-context', html_page_context) return { 'version': '0.1', 'parallel_read_safe': True, 'parallel_write_safe': True, } Spec: http://www.sphinx-doc.org/en/master/extdev/tutorial.html#the-setup-function og_site_url = ‘http://example.com/’ og_twitter_site = ‘@sphinxjp` conf.py ogtag.py
  22. 22. Sphinx拡張入門 (3/3) app.connect() でイベントハンドラを登録。この例では html-page-context イベントというHTMLビルド直前のス テージをフックして、ページ内のデータを収集してogp metaタグを追加する html_page_context 関数を登録しま す 22 def setup(app): app.add_config_value('og_site_url', None, 'html') app.add_config_value('og_twitter_site', None, 'html') app.connect('html-page-context', html_page_context) return { 'version': '0.1', 'parallel_read_safe': True, 'parallel_write_safe': True, } Spec: http://www.sphinx-doc.org/en/master/extdev/tutorial.html#the-setup-function ogtag.py
  23. 23. 23
  24. 24. フック関数の動作 (1/4) html-page-context イベントでogpタグをレンダリングする ためにdoctreeからデータを集めます。 doctreeはドキュメント(1ファイル)のAST (Abstract Syntax Tree: 抽象構文木)です。Sphinx拡張はVisitorパターンで doctreeからデータを集められます。 24 def html_page_context(app, pagename, templatename, context, doctree): if not doctree: return # walk over the `doctree` structure using visitor pattern ogtag.py Spec: http://www.sphinx-doc.org/en/master/extdev/appapi.html#event-html-page-context
  25. 25. フック関数の動作 (2/4) 25 og:image タグのための画像をdoctreeから探します。 imageノードというのをdoctreeから探して1つめを使ってま す。 class Visitor: def dispatch_visit(self, node): … # collect first image node if isinstance(node, nodes.image): self.images.append(node) … def get_og_image_url(self, page_url): if self.images: return urljoin(page_url, self.images[0]['uri']) else: return None Spec: http://docutils.sourceforge.net/docs/ref/doctree.html ogtag.py
  26. 26. フック関数の動作 (3/4) og:descriptionにはページの概要文のためのテキストを持 たせます。この拡張では3セクション分のテキストを集めま した 26 class Visitor: def dispatch_visit(self, node): … # collect page text from the first 3 sections if self.n_sections < 3: # collect text elements if isinstance(node, nodes.paragraph): self.text_list.append(node.astext()) … def get_og_description(self): text = ' '.join(self.text_list) if len(text) > 200: text = text[:197] + '...' return text Spec: http://docutils.sourceforge.net/docs/ref/doctree.html ogtag.py
  27. 27. フック関数の動作 (4/4) SphinxのHTML出力では context['metatags'] にある HTMLのメタタグを文字列としてそのまま使います。 この拡張では、そこにogpタグを追加します。 27 def html_page_context(app, pagename, templatename, context, doctree): kw = collect_ogp_data(doctree) # collect data fragments context['metatags'] += ””” <meta property="og:site_name" content="{sitetitle}"> <meta property="og:title" content="{pagetitle}"> <meta property="og:description" content="{description}"> ...snip... ”””.format(**kw) ogtag.py Ref: https://github.com/sphinx-doc/sphinx/blob/c307787/sphinx/builders/html.py#L1343
  28. 28. 28
  29. 29. make html 29 import sys import os sys.path.append(os.path.abspath('_ext')) # path where ogtag.py extensions = { ‘ogtag’, # python module names of extension } og_site_url = 'http://sphinx-users.jp/' # base url path for og:url tag og_twitter_site = '@sphinxjp' # twitter account for twitter:site. conf.py $ make html … Build finished. The HTML pages are in _build/html. $ <deploy _build/html> command-line
  30. 30. SNSへの投稿を検証 Facebook ● https://developers.facebook.com/tools/debug/sharing/ Twitter ● https://cards-dev.twitter.com/validator 30
  31. 31. 31
  32. 32. Next Steps. ● Sphinx拡張の公式チュートリアル ○ http://www.sphinx-doc.org/en/master/extdev/tuto rial.html ● Sphinx拡張をPyPIで探そう ○ https://pypi.org/search/?q=&o=&c=Framework+ %3A%3A+Sphinx+%3A%3A+Extension ● Sphinx OGP拡張 ○ http://sphinx-users.jp/cookbook/ogp/index.html 32
  33. 33. リファレンス ● SphinxでHTMLにOGPタグ出力 - 清水川Web ○ http://www.freia.jp/taka/blog/sphinx-ogp-support/in dex.html ● Twitter/Facebookへのページシェアでコンテンツを埋 め込む(OGP) -Python製ドキュメンテーションビル ダー、Sphinxの日本ユーザ会 ○ http://sphinx-users.jp/cookbook/ogp/index.html ● OGP ○ http://ogp.me/ 33
  34. 34. Questions? @shimizukawa 34

×