Browse Source

It is now possible to add and run template hooks.

sh4nks 11 years ago
parent
commit
50852e7f7d

+ 3 - 0
flaskbb/app.py

@@ -38,6 +38,7 @@ from flaskbb.utils.permissions import can_post_reply, can_post_topic, \
     can_delete_topic, can_delete_post, can_edit_post, can_lock_topic, \
     can_move_topic
 from flaskbb.plugins.manager import PluginManager
+from flaskbb.plugins import hooks
 
 
 def create_app(config=None):
@@ -74,6 +75,8 @@ def create_app(config=None):
                 plugin_manager.plugins)
     )
 
+    app.jinja_env.globals.update(hooks=hooks)
+
     return app
 
 

+ 8 - 10
flaskbb/plugins/__init__.py

@@ -109,11 +109,11 @@ class Plugin(object):
 class HookManager(object):
     """Manages all available hooks.
 
-    A new hook can be created either that way::
+    A new hook can be created like this::
 
         hooks.new("testHook")
 
-    or like this::
+    To add a callback to the hook you need to do that::
 
         hooks.add("testHook", test_callback)
 
@@ -134,25 +134,21 @@ class HookManager(object):
     def __init__(self):
         self.hooks = {}
 
-    def new(self, name):
+    def new(self, name, hook):
         """Creates a new hook.
 
         :param name: The name of the hook.
         """
         if name not in self.hooks:
-            self.hooks[name] = Hook()
+            self.hooks[name] = hook
 
     def add(self, name, callback):
-        """Adds a callback to the hook. If the hook doesn't exist, it will
-        create a new one and add than the callback will be added.
+        """Adds a callback to the hook.
 
         :param name: The name of the hook.
 
         :param callback: The callback which should be added to the hook.
         """
-        if name not in self.hooks:
-            self.new(name)
-
         return self.hooks[name].add(callback)
 
     def remove(self, name, callback):
@@ -192,6 +188,8 @@ class Hook(object):
     def call(self, *args, **kwargs):
         """Runs all callbacks for the hook."""
         for callback in self.callbacks:
-            callback(*args, **kwargs)
+            return callback(*args, **kwargs)
 
 hooks = HookManager()
+hooks.new("beforeIndex", Hook())
+hooks.new("beforeBreadcrumb", Hook())

+ 6 - 0
flaskbb/plugins/example/__init__.py

@@ -9,6 +9,10 @@ def hello_world():
     flash("Hello World from {}".format(__plugin__), "success")
 
 
+def inject_hello_world():
+    return "<b>Hello World</b>"
+
+
 class ExamplePlugin(Plugin):
     @property
     def description(self):
@@ -20,9 +24,11 @@ class ExamplePlugin(Plugin):
 
     def enable(self):
         hooks.add("beforeIndex", hello_world)
+        hooks.add("beforeBreadcrumb", inject_hello_world)
 
     def disable(self):
         hooks.remove("beforeIndex", hello_world)
+        hooks.remove("beforeBreadcrumb", inject_hello_world)
 
     def install(self):
         pass

+ 8 - 6
flaskbb/plugins/manager.py

@@ -14,8 +14,7 @@ from werkzeug.utils import import_string
 
 class PluginManager(object):
 
-    def __init__(self, app=None, plugin_folder="plugins",
-                 base_plugin_package="plugins"):
+    def __init__(self, app=None, **kwargs):
         """Initializes the PluginManager. It is also possible to initialize the
         PluginManager via a factory. For example::
 
@@ -32,7 +31,7 @@ class PluginManager(object):
                                     same like the plugin_folder.
         """
         if app is not None:
-            self.init_app(app, plugin_folder, base_plugin_package)
+            self.init_app(app, **kwargs)
 
         # All loaded plugins
         self._plugins = []
@@ -40,10 +39,13 @@ class PluginManager(object):
         # All found plugins
         self._found_plugins = []
 
-    def init_app(self, app, plugin_folder, base_plugin_package):
+    def init_app(self, app, plugin_folder="plugins",
+                 base_plugin_package="plugins"):
         self.app = app
-        self.plugin_folder = os.path.join(self.app.root_path, "plugins")
-        self.base_plugin_package = ".".join([self.app.name, "plugins"])
+        self.plugin_folder = os.path.join(self.app.root_path, plugin_folder)
+        self.base_plugin_package = ".".join(
+            [self.app.name, base_plugin_package]
+        )
 
     @property
     def plugins(self):

+ 2 - 0
flaskbb/templates/forum/index.html

@@ -1,6 +1,8 @@
 {% extends theme("layout.html") %}
 {% block content %}
 
+    {{ hooks.call("beforeBreadcrumb") | safe }}
+
 <ol class="breadcrumb">
     <li><a href="{{ url_for('forum.index') }}">Forum</a></li>
 </ol>