Skip to content

Commit

Permalink
Add hooks to add css/javascript
Browse files Browse the repository at this point in the history
(specific for some pages using web.ctx)
Fixes #43
  • Loading branch information
GuillaumeDerval committed Mar 24, 2015
1 parent 8c08028 commit 8e16ffa
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 16 deletions.
39 changes: 24 additions & 15 deletions doc/dev_doc/hook_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,38 @@ List of hooks
-------------

Each hook available in INGInious is described here, starting with its name and parameters.
*css*
Used to add CSS files in the header.
Should return the path to a CSS file (relative to the root of INGInious).
*course_admin_menu* (*course*)
Used to add links to the administration menu. This hook should return a tuple (link,name)
where link is the relative link from the index of the course administration.
You can also return None.
*course_menu* (*course*)
Allows to add HTML to the menu displayed on the course page. Course is the course object related to the page.
Should return HTML or None.
*javascript_header*
Used to add Javascript files in the header.
Should return the path to a Javascript file (relative to the root of INGInious).
*javascript_footer*
Used to add Javascript files in the footer.
Should return the path to a Javascript file (relative to the root of INGInious).
*job_ended* (*jobid*, *task*, *statinfo*, *results*)
Called when a job has ended. *task* contains a Task object,
*statinfo* is a dictionnary containing various informations about the job.
*results* contains the results of the job.
*job_manager_init_done* (*job_manager*)
Called when a JobManager instance is inited. *job_manager* is the instance that was inited.
This hooks cannot be used by the plugins, as the backend is inited before the plugins.
*job_manager_exit* (*job_manager*)
Called when a JobManager received the exit signal, before the JobManager exits.
*modify_task_data* (*course*, *taskid*, *data*)
Allows to modify the task description before the initialisation of the Task object.
Changes are not saved to disk.
*new_job* (*jobid*, *task*, *statinfo*, *inputdata*)
Called when a job was just submitted. *task* contains a Task object,
*statinfo* is a dictionnary containing various informations about the job.
*inputdata* contains the answers that were submitted to INGInious.
*job_ended* (*jobid*, *task*, *statinfo*, *results*)
Called when a job has ended. *task* contains a Task object,
*statinfo* is a dictionnary containing various informations about the job.
*results* contains the results of the job.
*new_submission* (*submissionid*, *submission*, *jobid*, *inputdata*)
Called when a new submission is received.
*inputdata* contains the answers that were submitted to INGInious.
Expand All @@ -36,14 +55,4 @@ Each hook available in INGInious is described here, starting with its name and p
(submission_done is called after job_ended)
*template_helper* ()
Adds a new helper to the instance of TemplateHelper. Should return a tuple (name,func) where name is the name that will
be indicated when calling the TemplateHelper.call method, and func is the function that will be called.
*course_admin_menu* (*course*)
Used to add links to the administration menu. This hook should return a tuple (link,name)
where link is the relative link from the index of the course administration.
You can also return None.
*modify_task_data* (*course*, *taskid*, *data*)
Allows to modify the task description before the initialisation of the Task object.
Changes are not saved to disk.
*course_menu* (*course*)
Allows to add HTML to the menu displayed on the course page. Course is the course object related to the page.
Should return HTML or None.
be indicated when calling the TemplateHelper.call method, and func is the function that will be called.
47 changes: 47 additions & 0 deletions frontend/template_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
# License along with INGInious. If not, see <http://www.gnu.org/licenses/>.
""" Helper for the templates """

import web

from frontend.base import add_to_template_globals
import frontend.pages.course_admin.utils
from frontend.plugins.plugin_manager import PluginManager
Expand All @@ -36,7 +38,11 @@ class TemplateHelper(object):
_instance = None
_base_helpers = {"header_hook": (lambda **kwargs: generic_hook('header_html', **kwargs)),
"course_menu": (lambda **kwargs: generic_hook('course_menu', **kwargs)),
"javascript_header": (lambda **_: TemplateHelper._javascript_helper("header")),
"javascript_footer": (lambda **_: TemplateHelper._javascript_helper("footer")),
"css": (lambda **_: TemplateHelper._css_helper()),
"course_admin_menu": frontend.pages.course_admin.utils.get_menu}
WEB_CTX_KEY = "inginious_tpl_helper"

def __new__(cls, *args, **kwargs):
if not cls._instance:
Expand All @@ -58,3 +64,44 @@ def call(self, name, **kwargs):
return ""
else:
return helpers.get(name, None)(**kwargs)

def add_javascript(self, link, position="footer"):
""" Add a javascript file to load. Position can either be "header" or "footer" """
self._get_ctx()["javascript"][position].append(link)

def add_css(self, link):
""" Add a css file to load """
self._get_ctx()["css"].append(link)

@classmethod
def _javascript_helper(cls, position):
""" Add javascript links for the current page and for the plugins """
if position not in ["header", "footer"]:
position = "footer"

# Load javascript files from plugins
if position == "header":
entries = [entry for entry in PluginManager.get_instance().call_hook("javascript_header") if entry is not None]
else:
entries = [entry for entry in PluginManager.get_instance().call_hook("javascript_footer") if entry is not None]
# Load javascript for the current page
entries += cls.get_instance()._get_ctx()["javascript"][position]
entries = ["<script src='" + entry + "' type='text/javascript' charset='utf-8'></script>" for entry in entries]
return "\n".join(entries)

@classmethod
def _css_helper(cls):
""" Add CSS links for the current page and for the plugins """
entries = [entry for entry in PluginManager.get_instance().call_hook("css") if entry is not None]
# Load javascript for the current page
entries += cls.get_instance()._get_ctx()["css"]
entries = ["<link href='" + entry + "' rel='stylesheet'>" for entry in entries]
return "\n".join(entries)

def _get_ctx(self):
""" Get web.ctx object for the Template helper """
if self.WEB_CTX_KEY not in web.ctx:
web.ctx[self.WEB_CTX_KEY] = {
"javascript": {"footer": [], "header": []},
"css": []}
return web.ctx.get(self.WEB_CTX_KEY)
5 changes: 4 additions & 1 deletion templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@

$if "header" in content:
$:content.header


$:template_helper.call('css')
$:template_helper.call('javascript_header')
$:template_helper.call('header_hook')
</head>

Expand Down Expand Up @@ -124,5 +126,6 @@
<script type="text/javascript" src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">google.load('visualization', '1.0', {'packages':['corechart']});</script>
$:template_helper.call('javascript_footer')
</body>
</html>

0 comments on commit 8e16ffa

Please sign in to comment.