forked from enterstudio/ckanext-datagovau
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add hierarchical organisation structure
- Loading branch information
Alex Sadleir
committed
Nov 12, 2014
1 parent
04b090b
commit 1cf2f23
Showing
11 changed files
with
1,106 additions
and
167 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import logging | ||
|
||
import ckan.plugins as p | ||
import ckan.logic as logic | ||
from ckanext.datagovau.model import GroupTreeNode | ||
|
||
log = logging.getLogger(__name__) | ||
_get_or_bust = logic.get_or_bust | ||
|
||
|
||
@logic.side_effect_free | ||
def group_tree(context, data_dict): | ||
'''Returns the full group tree hierarchy. | ||
:returns: list of top-level GroupTreeNodes | ||
''' | ||
model = _get_or_bust(context, 'model') | ||
group_type = data_dict.get('type', 'group') | ||
return [_group_tree_branch(group, type=group_type) | ||
for group in model.Group.get_top_level_groups(type=group_type)] | ||
|
||
|
||
@logic.side_effect_free | ||
def group_tree_section(context, data_dict): | ||
'''Returns the section of the group tree hierarchy which includes the given | ||
group, from the top-level group downwards. | ||
:param id: the id or name of the group to inclue in the tree | ||
:returns: the top GroupTreeNode of the tree section | ||
''' | ||
group_name_or_id = _get_or_bust(data_dict, 'id') | ||
model = _get_or_bust(context, 'model') | ||
group = model.Group.get(group_name_or_id) | ||
if group is None: | ||
raise p.toolkit.ObjectNotFound | ||
group_type = data_dict.get('type', 'group') | ||
if group.type != group_type: | ||
how_type_was_set = 'was specified' if data_dict.get('type') \ | ||
else 'is filtered by default' | ||
raise p.toolkit.ValidationError( | ||
'Group type is "%s" not "%s" that %s' % | ||
(group.type, group_type, how_type_was_set)) | ||
root_group = (group.get_parent_group_hierarchy(type=group_type) or [group])[0] | ||
return _group_tree_branch(root_group, highlight_group_name=group.name, | ||
type=group_type) | ||
|
||
|
||
def _group_tree_branch(root_group, highlight_group_name=None, type='group'): | ||
'''Returns a branch of the group tree hierarchy, rooted in the given group. | ||
:param root_group_id: group object at the top of the part of the tree | ||
:param highlight_group_name: group name that is to be flagged 'highlighted' | ||
:returns: the top GroupTreeNode of the tree | ||
''' | ||
nodes = {} # group_id: GroupTreeNode() | ||
root_node = nodes[root_group.id] = GroupTreeNode( | ||
{'id': root_group.id, | ||
'name': root_group.name, | ||
'title': root_group.title}) | ||
if root_group.name == highlight_group_name: | ||
nodes[root_group.id].highlight() | ||
highlight_group_name = None | ||
for group_id, group_name, group_title, parent_id in \ | ||
root_group.get_children_group_hierarchy(type=type): | ||
node = GroupTreeNode({'id': group_id, | ||
'name': group_name, | ||
'title': group_title}) | ||
nodes[parent_id].add_child_node(node) | ||
if highlight_group_name and group_name == highlight_group_name: | ||
node.highlight() | ||
nodes[group_id] = node | ||
return root_node |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from bisect import bisect_right | ||
|
||
|
||
class GroupTreeNode(dict): | ||
'''Represents a group in a tree, used when rendering the tree. | ||
Is a dict, with links to child GroupTreeNodes, so that it is already | ||
'dictized' for output from the logic layer. | ||
''' | ||
def __init__(self, group_dict): | ||
dict.__init__(self) | ||
self.update(group_dict) | ||
self['highlighted'] = False | ||
self['children'] = [] | ||
# self._children_titles has a 1:1 relationship with values in | ||
# self.['children'], and is used to help keep them sorted by title | ||
self._children_titles = [] | ||
|
||
def add_child_node(self, child_node): | ||
'''Adds the child GroupTreeNode to this node, keeping the children | ||
in alphabetical order by title. | ||
''' | ||
title = child_node['title'] | ||
insert_index = bisect_right(self._children_titles, title) | ||
self['children'].insert(insert_index, child_node) | ||
self._children_titles.insert(insert_index, title) | ||
|
||
def highlight(self): | ||
'''Flag this group to indicate it should be shown highlighted | ||
when rendered.''' | ||
self['highlighted'] = True | ||
|
||
|
||
def group_dictize(group): | ||
'''Convert a Group object into a dict suitable for GroupTreeNode | ||
Much simpler and quicker to do this than run than the full package_show. | ||
''' | ||
return {'id': group.id, | ||
'name': group.name, | ||
'title': group.title, | ||
'type': group.type} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{% ckan_extends %} | ||
|
||
{% block organization_description %} | ||
{{ super() }} | ||
|
||
{# TODO: Add JSTree #} | ||
|
||
<div id="publisher-tree"> | ||
{% snippet 'organization/snippets/organization_tree.html', top_nodes=[h.get_action('group_tree_section', {'id': c.group_dict.id, 'type': c.group_dict.type})] %} | ||
</div> | ||
{% endblock %} |
19 changes: 19 additions & 0 deletions
19
ckanext/datagovau/templates/organization/snippets/organization_form.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{% ckan_extends %} | ||
|
||
{% block basic_fields %} | ||
{{ super() }} | ||
|
||
<div class="control-group"> | ||
<label class="control-label" for="field-parent">{{ _("Parent") }}</label> | ||
<div class="controls"> | ||
<select id="field-parent" name="groups__0__name" data-module="autocomplete"> | ||
{% set selected_parent = (data.get('groups') or [{'name': ''}])[0]['name'] %} {{ selected_parent }} | ||
<option value="" {% if not selected_parent %} selected="selected" {% endif %}>{{ _('None - top level') }}</option> | ||
{% for group in c.allowable_parent_groups %} | ||
<option value="{{ group.name }}" {% if group.name == selected_parent %}selected="selected"{% endif %}>{{ group.title }}</option> | ||
{% endfor %} | ||
</select> | ||
</div> | ||
</div> | ||
|
||
{% endblock %} |
32 changes: 32 additions & 0 deletions
32
ckanext/datagovau/templates/organization/snippets/organization_tree.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{# | ||
Displays a tree of organzations | ||
|
||
NB This template can be slow because it is recursive and uses link_for. At | ||
DGU we speeded up display of the tree 10 times (necessary as we have 1000 | ||
organizations) by replacing this template with a recursive code routine: | ||
https://github.com/datagovuk/ckanext-dgu/blob/5fb78b354517c2198245bdc9c98fb5d6c82c6bcc/ckanext/dgu/lib/helpers.py#L140 | ||
|
||
orgs - List of organizations | ||
|
||
Example: | ||
|
||
{% snippet 'organization/snippets/organization_tree.html', top_nodes=h.get_action('group_tree', {'type': 'organization'}) %} | ||
|
||
#} | ||
<ul> | ||
{% for node in top_nodes recursive %} | ||
<li id="node_{{ node.name }}"> | ||
{% if node.highlighted %} | ||
<strong> | ||
{% endif %} | ||
{% link_for node.title, controller='organization', action='read', id=node.name %} | ||
{% if node.highlighted %} | ||
</strong> | ||
{% endif %} | ||
|
||
{% if node.children %} | ||
<ul> {{ loop(node.children) }} </ul> | ||
{% endif %} | ||
</li> | ||
{% endfor %} | ||
</ul> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters