Skip to content

Commit

Permalink
[#847] Add Fanstatic tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
Sean Hammond committed Nov 27, 2013
1 parent 2d2b12f commit 833536e
Show file tree
Hide file tree
Showing 15 changed files with 241 additions and 1 deletion.
Empty file.
103 changes: 103 additions & 0 deletions ckanext/example_theme/v15_fanstatic/fanstatic/example_theme.css
@@ -0,0 +1,103 @@
/* =====================================================
The "account masthead" bar across the top of the site
===================================================== */

.account-masthead {
background-color: rgb(40, 40, 40);
}
/* The "bubble" containing the number of new notifications. */
.account-masthead .account .notifications a span {
background-color: black;
}
/* The text and icons in the user account info. */
.account-masthead .account ul li a {
color: rgba(255, 255, 255, 0.6);
}
/* The user account info text and icons, when the user's pointer is hovering
over them. */
.account-masthead .account ul li a:hover {
color: rgba(255, 255, 255, 0.7);
background-color: black;
}


/* ========================================================================
The main masthead bar that contains the site logo, nav links, and search
======================================================================== */

.masthead {
background-color: #3d3d3d;
}
/* The "navigation pills" in the masthead (the links to Datasets,
Organizations, etc) when the user's pointer hovers over them. */
.masthead .navigation .nav-pills li a:hover {
background-color: rgb(48, 48, 48);
color: white;
}
/* The "active" navigation pill (for example, when you're on the /dataset page
the "Datasets" link is active). */
.masthead .navigation .nav-pills li.active a {
background-color: rgb(74, 74, 74);
}
/* The "box shadow" effect that appears around the search box when it
has the keyboard cursor's focus. */
.masthead input[type="text"]:focus {
-webkit-box-shadow: inset 0px 0px 2px 0px rgba(0, 0, 0, 0.7);
box-shadow: inset 0px 0px 2px 0px rgba(0, 0, 0, 0.7);
}


/* ===========================================
The content in the middle of the front page
=========================================== */

/* Remove the "box shadow" effect around various boxes on the page. */
.box {
box-shadow: none;
}
/* Remove the borders around the "Welcome to CKAN" and "Search Your Data"
boxes. */
.hero .box {
border: none;
}
/* Change the colors of the "Search Your Data" box. */
.homepage .module-search .module-content {
color: rgb(68, 68, 68);
background-color: white;
}
/* Change the background color of the "Popular Tags" box. */
.homepage .module-search .tags {
background-color: rgb(61, 61, 61);
}
/* Remove some padding. This makes the bottom edges of the "Welcome to CKAN"
and "Search Your Data" boxes line up. */
.module-content:last-child {
padding-bottom: 0px;
}
.homepage .module-search {
padding: 0px;
}
/* Add a border line between the top and bottom halves of the front page. */
.homepage [role="main"] {
border-top: 1px solid rgb(204, 204, 204);
}


/* ====================================
The footer at the bottom of the site
==================================== */

.site-footer,
body {
background-color: rgb(40, 40, 40);
}
/* The text in the footer. */
.site-footer,
.site-footer label,
.site-footer small {
color: rgba(255, 255, 255, 0.6);
}
/* The link texts in the footer. */
.site-footer a {
color: rgba(255, 255, 255, 0.6);
}
53 changes: 53 additions & 0 deletions ckanext/example_theme/v15_fanstatic/plugin.py
@@ -0,0 +1,53 @@
import ckan.plugins as plugins
import ckan.plugins.toolkit as toolkit


def most_popular_groups():
'''Return a sorted list of the groups with the most datasets.'''

# Get a list of all the site's groups from CKAN, sorted by number of
# datasets.
groups = toolkit.get_action('group_list')(
data_dict={'sort': 'packages desc', 'all_fields': True})

# Truncate the list to the 10 most popular groups only.
groups = groups[:10]

return groups


class ExampleThemePlugin(plugins.SingletonPlugin):
'''An example theme plugin.
'''
plugins.implements(plugins.IConfigurer)

# Declare that this plugin will implement ITemplateHelpers.
plugins.implements(plugins.ITemplateHelpers)

def update_config(self, config):

# Add this plugin's templates dir to CKAN's extra_template_paths, so
# that CKAN will use this plugin's custom templates.
toolkit.add_template_directory(config, 'templates')

# Add this plugin's public dir to CKAN's extra_public_paths, so
# that CKAN will use this plugin's custom static files.
toolkit.add_public_directory(config, 'public')

# Register this plugin's fanstatic directory with CKAN.
# Here, 'fanstatic' is the path to the fanstatic directory
# (relative to this plugin.py file), and 'example_theme' is the name
# that we'll use to refer to this fanstatic directory from CKAN
# templates.
toolkit.add_resource('fanstatic', 'example_theme')

def get_helpers(self):
'''Register the most_popular_groups() function above as a template
helper function.
'''
# Template helper function names should begin with the name of the
# extension they belong to, to avoid clashing with functions from
# other extensions.
return {'example_theme_most_popular_groups': most_popular_groups}
12 changes: 12 additions & 0 deletions ckanext/example_theme/v15_fanstatic/templates/base.html
@@ -0,0 +1,12 @@
{% ckan_extends %}

{% block styles %}
{{ super() }}

{# Import example_theme.css using Fanstatic.
'example_theme/' is the name that the example_theme/fanstatic directory
was registered with when the toolkit.add_resource() function was called.
'example_theme.css' is the path to the CSS file, relative to the root of
the fanstatic directory. #}
{% resource 'example_theme/example_theme.css' %}
{% endblock %}
1 change: 1 addition & 0 deletions ckanext/example_theme/v15_fanstatic/templates/home
1 change: 1 addition & 0 deletions ckanext/example_theme/v15_fanstatic/templates/snippets
67 changes: 67 additions & 0 deletions doc/theming/fanstatic.rst
@@ -0,0 +1,67 @@
=================================================
Adding CSS and |javascript| files using Fanstatic
=================================================

.. versionadded:: 2.0

If you're adding CSS files to your theme, you can add them
using `Fanstatic <http://www.fanstatic.org/>`_ rather than the simple
:ref:`extra_public_paths` method described in :doc:`static-files`.
If you're adding a |javascript| module, you *must* use Fanstatic.

Using Fanstatic to add |javascript| and CSS files takes advantage
of Fanstatic's features, such as automatically serving minified files in
production, caching and bundling files together to reduce page load times,
specifying dependencies between files so that the files a page needs (and only
the files it needs) are always loaded, and other tricks to optimize page load
times.

.. note::

CKAN will only serve ``*.js`` and ``*.css`` files as Fanstatic resources,
other types of static files (eg. image files, PDF files) must be added
using the :ref:`extra_public_paths` method described in :doc:`static-files`.

Adding a custom |javascript| or CSS file to CKAN using Fanstatic is simple.
We'll demonstrate by changing our previous custom CSS example (see :doc:`css`)
to serve the CSS file with Fanstatic.

1. First, create a ``fanstatic`` directory in your extension and move the CSS
file from ``public`` into ``fanstatic``::

ckanext-example_theme/
public/
promoted-image.jpg
fanstatic/
example_theme.css

2. Use CKAN's :py:func:`~ckan.plugins.toolkit.add_resource()` function to
register your fanstatic directory with CKAN. Edit the ``update_config()``
method in your ``plugin.py`` file:

.. literalinclude:: /../ckanext/example_theme/v15_fanstatic/plugin.py
:pyobject: ExampleThemePlugin.update_config

3. Finally, edit your extension's ``templates/base.html`` file and use CKAN's
custom Jinja2 tag ``{% resource %}`` instead of the normal ``<link>`` tag to
import the file:

.. literalinclude:: /../ckanext/example_theme/v15_fanstatic/templates/base.html

.. note::

You can put ``{% resource %}`` tags anywhere in any template, and Fanstatic
will insert and necessary ``<style>`` and ``<script>`` tags to include your
CSS and |javascript| files and their dependencies in the right places in
the HTML output (CSS files in the HTML ``<head>``, |javascript| files at
the bottom of the page).

Resources will *not* be included on the line where the ``{% resource %}``
tag is.

.. note::

A config file can be used to configure how Fanstatic should serve each resource
file (whether or not to bundle files, what order to include files in, whether
to include files at the top or bottom of the page, dependencies between files,
etc.) See :doc:`/resources` for details.
1 change: 1 addition & 0 deletions doc/theming/index.rst
Expand Up @@ -42,6 +42,7 @@ your custom CKAN theme.
templates
static-files
css
fanstatic
javascript
best-practices
jinja-tags
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Expand Up @@ -93,7 +93,8 @@
'example_theme_v12_extra_public_dir = ckanext.example_theme.v12_extra_public_dir.plugin:ExampleThemePlugin',
'example_theme_v13_custom_css = ckanext.example_theme.v13_custom_css.plugin:ExampleThemePlugin',
'example_theme_v14_more_custom_css = ckanext.example_theme.v14_more_custom_css.plugin:ExampleThemePlugin',
'example_theme_v15_initialize_a_javascript_module = ckanext.example_theme.v15_initialize_a_javascript_module.plugin:ExampleThemePlugin',
'example_theme_v15_fanstatic = ckanext.example_theme.v15_fanstatic.plugin:ExampleThemePlugin',
'example_theme_v16_initialize_a_javascript_module = ckanext.example_theme.v16_initialize_a_javascript_module.plugin:ExampleThemePlugin',
],
'ckan.system_plugins': [
'domain_object_mods = ckan.model.modification:DomainObjectModificationExtension',
Expand Down

0 comments on commit 833536e

Please sign in to comment.