lektor_admin_extra.py 5.34 KB
Newer Older
Pascal's avatar
Pascal committed
1
2
3
4
5
# -*- coding: utf-8 -*-
from flask import Blueprint, \
                  current_app, \
                  url_for, \
                  render_template
Pascal's avatar
Pascal committed
6
from lektor.pluginsystem import Plugin
Pascal's avatar
Pascal committed
7
8
from lektor.admin.modules import serve, dash

Pascal's avatar
Pascal committed
9
utilsbp = Blueprint('admin_utils', __name__,
Pascal's avatar
Pascal committed
10
11
12
13
14
                           url_prefix='/admin-pages',
                           static_folder='static',
                           template_folder='templates'
                           )

Pascal's avatar
Pascal committed
15
def add_content(contents, extra_routes=None):
Pascal's avatar
Pascal committed
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
    """
    insert buttons in html pages

    see rewrite_html_for_editing in lektor/admin/modules/serve.py
    """
    head_endpos = contents.find(b'</head>')
    body_endpos = contents.find(b'</body>')
    if head_endpos >= 0 and body_endpos >= 0:
        # html page
        return bytes(contents[:head_endpos] +
                render_template('admin_style.html').encode('utf-8') +
                contents[head_endpos:body_endpos] +
                render_template('admin_messages.html').encode('utf-8') +
                render_template('admin_buttons.html', buttons=extra_routes).encode('utf-8') +
                contents[body_endpos:])
    # dash or iframe ?
    return bytes(contents +
            render_template('admin_style.html').encode('utf-8') +
            render_template('admin_buttons.html', buttons=extra_routes).encode('utf-8')
            )

class AdminExtraPlugin(Plugin):
    name = 'admin-extra'
    description = u'Add buttons on lektor admin pages.'
Pascal's avatar
Pascal committed
40
    right_buttons = { 'serve' : [], 'dash': [] }
Pascal's avatar
Pascal committed
41
42
43
    help_data = {
            'index': []
            }
Pascal's avatar
Pascal committed
44
    help_dir = None
Pascal's avatar
Pascal committed
45
    bp = utilsbp
Pascal's avatar
Pascal committed
46

Pascal's avatar
Pascal committed
47
48
49
50
    def emit(self, event, **kwargs):
        """ lektor bug, now fixed #859 """
        return self.env.plugin_controller.emit(self.id + "-" + event, **kwargs)

Pascal's avatar
Pascal committed
51
    #pylint: disable=unused-variable
Pascal's avatar
Pascal committed
52
    def on_setup_env(self, *args, **extra):
Pascal's avatar
Pascal committed
53
54
55
56
57
58
59
        """
        initialize routes and buttons
        top help page redirects to the directory
        under self.get_config().get('help_pages')
        (which default to /admin-pages)
        or a default help page.
        """
Pascal's avatar
Pascal committed
60

Pascal's avatar
Pascal committed
61
        self.parse_config()
Pascal's avatar
Pascal committed
62

Pascal's avatar
Pascal committed
63
64
65
66
        @serve.bp.before_app_first_request
        def setup_blueprint():
            app = current_app
            app.register_blueprint(utilsbp)
Pascal's avatar
Pascal committed
67
            # only if no help pages defined
Pascal's avatar
Pascal committed
68
            if self.help_dir is not None:
Pascal's avatar
Pascal committed
69
70
                print("[admin-extra] use %s help pages"%self.help_dir)
                self.add_button(self.help_dir, 'help', '?' )
Pascal's avatar
Pascal committed
71
            else:
Pascal's avatar
Pascal committed
72
73
74
                print("[admin-extra] use default page")
                self.add_button( url_for('admin_utils.help'), 'help', '?' )
            print("[admin-extra] buttons = %s"%self.right_buttons)
Pascal's avatar
Pascal committed
75
76
77
78
79
80

        @serve.bp.after_request
        #pylint: disable=unused-variable
        def after_request_serve(response):
            if response.mimetype == "text/html":
                response.direct_passthrough = False
Pascal's avatar
Pascal committed
81
                response.set_data(add_content(response.get_data(),self.buttons('serve')))
Pascal's avatar
Pascal committed
82
83
84
85
86
87
88
            return response

        @dash.bp.after_request
        #pylint: disable=unused-variable
        def after_request_dash(response):
            if response.mimetype == "text/html":
                response.direct_passthrough = False
Pascal's avatar
Pascal committed
89
                response.set_data(add_content(response.get_data(),self.buttons('dash')))
Pascal's avatar
Pascal committed
90
91
            return response

Pascal's avatar
Pascal committed
92
        @utilsbp.route('/help')
Pascal's avatar
Pascal committed
93
        #pylint: disable=unused-variable
Pascal's avatar
Pascal committed
94
95
        def help():
            pad = self.env.new_pad()
Pascal's avatar
Pascal committed
96
            return render_template('help.html', this=self.help_data, site=pad, help_root=self.help_dir)
Pascal's avatar
Pascal committed
97
98
            #return self.env.render_template('help.html', this=self.help_data)

Pascal's avatar
Pascal committed
99
100
    def buttons(self, bp, **kwargs):
        return [ b for b,f in self.right_buttons[bp] if f is None or f(**kwargs) ]
Pascal's avatar
Pascal committed
101

Pascal's avatar
Pascal committed
102
    def add_button(self, route, title, html_entity, bp=['serve','dash'], ignore=None, index=None):
Pascal's avatar
doc    
Pascal committed
103
        print("[admin-extra] register button %s -> %s"%(title, route))
Pascal's avatar
Pascal committed
104
        for b in bp:
Pascal's avatar
Pascal committed
105
106
107
108
            if index is None or index > len(self.right_buttons[b]):
                self.right_buttons[b].append( ((route, title, html_entity), ignore) )
            else:
                self.right_buttons[b].insert(index, ((route, title, html_entity), ignore) )
Pascal's avatar
Pascal committed
109
110
111
112
    def add_serve_button(self, *args, **kwargs):
        self.add_button(*args, bp=['serve'], **kwargs)
    def add_dash_button(self, *args, **kwargs):
        self.add_button(*args, bp=['dash'], **kwargs)
Pascal's avatar
Pascal committed
113
114
    def add_help_page(self, url, item):
        self.help_data['index'].append( (url, item) )
Pascal's avatar
Pascal committed
115
116

    def parse_config(self):
Pascal's avatar
Pascal committed
117
118
119
120
121
122
123
124
125
126
127
        """
        register buttons defined in configs/admin-extra.ini

        Example
        ```
        [button.addpage]
        url = /admin/root:add-child
        title = nouvelle page
        html = +
        ```
        """
Pascal's avatar
Pascal committed
128
129
130
131
132
133
134
135
136
137
138
        config = self.get_config()
        self.help_dir = config.get('help_pages', None)
        prefix = 'button.'
        button_names = [ s[len(prefix):] for s in config.sections() if s[:len(prefix)] == prefix ]
        for name in button_names:
            get = lambda k: config.get(prefix+name+'.'+k,None)
            (url, html, title, index) = map(get, ['url','html','title', 'index'])
            scope = ['serve','dash']
            if get('scope'):
                scope = [s for s in get('scope').split(',') if s in ['serve','dash']]
            self.add_button(url, title, html, bp=scope, index=index)