title: Best practice for Django components
body: <p>Django provides a means of collecting assets into its Widget framework, and in turn using a form to present it, but how about doing this outside the forms framework?</p>
  
  <p>For example, let's say I just want a simple, self-enclosed web component that requires two .js files, a CSS file, a template, and is backed by a view to generate some data.  This isn't a "form" because it's not intended to collect input. Rather, assume it's, say, a customized scrollbar.  I can't seem to find the right match for this usage pattern even though it seems common and straight-forward.</p>
  
  <p>To do this now seems to mean adding the CSS to the top-level template; the JS to the template (or script tags arbitrarily in the included document); and then rendering the form as an include.  But wouldn't it be easier to have something like:</p>
  
  <pre><code>class ScrollBar(...):
      template_name = ...
  
      class Assets:
          ...
  </code></pre>
  
  <p>and then rendering it via a templatetag, but with the ability for a context processor or other hook to extract the assets into their appropriate places in the page?</p>
  
  <p>Something like:</p>
  
  <p>index.html:</p>
  
  <pre><code>&lt;html&gt;
  &lt;head&gt;
      ...
      {% compressed_css %}
  &lt;/head&gt;
  &lt;body&gt;
      ...
      {% compressed_js %}
      {% block content %}
      {% endblock %}
  &lt;/body&gt;
  </code></pre>
  
  <p>scrollbar-using-page.html</p>
  
  <pre><code>{% extends "index" %}
  {% block content %}
  {% scrollbar args %}
  {% endblock %}
  </code></pre>
  
  <p>with the end result being the scrollbar's template is rendered with the specified args, and its JS and CSS are merged into the compressed_css and compressed_js areas, respectively, above?</p>
  
  <p>I think we get there almost 100% via this approach, without the compressed_js/compressed_css sections, which raises the question of whether then we just included these in all shared pages.  (Alternatively, we could use nested/inherited blocks.)</p>
  
  <p>Adam</p>