気ままなタンス*プログラミングなどのノートブック

プログラミングやRPGツクール、DTM等について、学んだことや備忘録をアウトプットとして残し、情報を必要としている誰かにとって「かゆいところに手が届く」ブログとなることを願いながら記事を書いています。

【Django】django-markitupの使い方(2015年)

スポンサーリンク

markitupとは?

マークアップテキストエディタ。
jQueryのプラグインとして提供されている。

markItUp! Universal Markup jQuery Editor :::

Djangoで利用するには?

素敵なことに、Pypiにmarkitup用のパッケージが提供されているので
そちらを利用する

django-markitup

pypi.python.org

インストール方法

  • パッケージのインストール

$ pip install django-markitup

$ pip install Markdown

  • settings.pyのINSTALLED_APPSに追記
INSTALLED_APPS = (
   ..., 
   'markitup',
)
  • settings.pyにmarkitup用の定数をセット
# Markitupに利用するフィルター(今回はマークダウンのためmarkdown.markdownを利用)
# wikiやtextileの場合、それらに準じたライブラリを指定する
MARKITUP_FILTER = ('markdown.markdown', {'safe_mode': True})
  • markitup関係のファイルをSTATICFILES_DIRSから参照できる位置にコピー

仮にSTATICFILE_DIRSから見える位置をdjango-project/staticとする

BASE_DIR = os.path.dirname(os.path.dirname(__file__))

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static')
)

[VIRTUALENV]/Lib/site-packages/markitup/static配下にあるmarkitupフォルダを
django-project/static配下にコピーする


具体例(僕の環境の場合)

・virtualenv
D:\virtualenv\venv-django167-pv34

・markitupのパッケージ(コピー元フォルダ)
D:\virtualenv\venv-django167-pv34\Lib\site-packages\markitup\static\markitup

・プロジェクトフォルダ(コピー先フォルダ)
D:\django-product\project\static\

  • コピー先フォルダを基準として、各ファイルの設定を行う

○markdownアイコン表記の日本語化
対象ファイル:django-project/static/markitup/sets/markdown/sets/sets.js

// 

// -------------------------------------------------------------------
// markItUp!
// -------------------------------------------------------------------
// Copyright (C) 2008 Jay Salvat
// http://markitup.jaysalvat.com/
// -------------------------------------------------------------------
// MarkDown tags example
// http://en.wikipedia.org/wiki/Markdown
// http://daringfireball.net/projects/markdown/
// -------------------------------------------------------------------
// Feel free to add more tags
// -------------------------------------------------------------------
mySettings = {
  onShiftEnter:    {keepDefault:false, openWith:'\n\n'},
  markupSet: [
    {name:'見出し1', key:'1', placeHolder:'ここにタイトルを入力', closeWith:function(markItUp) { return miu.markdownTitle(markItUp, '=') } },
    {name:'見出し2', key:'2', placeHolder:'ここにタイトルを入力', closeWith:function(markItUp) { return miu.markdownTitle(markItUp, '-') } },
    {name:'見出し3', key:'3', openWith:'### ', placeHolder:'ここにタイトルを入力' },
    {name:'見出し4', key:'4', openWith:'#### ', placeHolder:'ここにタイトルを入力' },
    {name:'見出し5', key:'5', openWith:'##### ', placeHolder:'ここにタイトルを入力' },
    {name:'見出し6', key:'6', openWith:'###### ', placeHolder:'ここにタイトルを入力' },
    {separator:'---------------' },    
    {name:'強調', key:'B', openWith:'**', closeWith:'**'},
    {name:'斜体', key:'I', openWith:'_', closeWith:'_'},
    {separator:'---------------' },
    {name:'順不同リスト', openWith:'- ' },
    {name:'番号付リスト', openWith:function(markItUp) {
      return markItUp.line+'. ';
    }},
    {separator:'---------------' },
    {name:'画像', key:'P', replaceWith:'![[![Alternative text]!]]([![Url:!:http://]!] "[![Title]!]")'},
    {name:'リンク', key:'L', openWith:'[', closeWith:']([![Url:!:http://]!] "[![Title]!]")', placeHolder:'Your text to link here...' },
    {separator:'---------------'},  
    {name:'引用', openWith:'> '},
    {name:'コードブロック', openWith:'(!(\t|!|`)!)', closeWith:'(!(`)!)'},
    {separator:'---------------'},
    {name:'プレビュー', call:'preview', className:"preview"}
  ]
}

// mIu nameSpace to avoid conflict.
miu = {
  markdownTitle: function(markItUp, char) {
    heading = '';
    n = $.trim(markItUp.selection||markItUp.placeHolder).length;
    // work around bug in python-markdown where header underlines must be at least 3 chars
    if (n < 3) { n = 3; }
    for(i = 0; i < n; i++) {
      heading += char;
    }
    return '\n'+heading;
  }
}

利用方法

  • フォームのwidgetにmarkitupを指定
from markitup.widgets import MarkItUpWidget
from django import forms
class AnyForm(forms.Form):
   mark = forms.CharField(widget=MarkItUpWidget())
  • ビューでフォームを作成し、テンプレートに渡す
from anyproject.forms import AnyForm
from django.shortcuts import render_to_response
from django.template import RequestContext
def any_view(request):
   form = AnyForm()
   return render_to_response('any/page.html', dict(form=form), 
                               RequestContext(request) )
  • テンプレートで利用(通常と同様)

{{ form.mark }}

現状、わかっている範囲で、できること・できないことをまとめる

  • できること

・マークダウン全般
・独自ボタンの追加
・スキンのカスタマイズ

  • (標準で)できないこと

・画像のアップロード
・シンタックスハイライト

はまりどころ

・MarkitupのファイルをSTATICFILESから見える位置にコピーするのを忘れると、
 Ajax関係のリクエストで落ちる(csrf_tokenの検証に失敗するエラー)

・ページのレイアウトをカスタマイズしたい場合、
TEMPLATE_DIRSで設定したテンプレートディレクトリの直下に
markdownフォルダを作成し、上書きさせる必要がある。

※preview.htmlの内容に追記したい場合
コピー元:django-project/static/markitup/preview.html
コピー先:TEMPLATE_DIR/markdown/preview.html