├── .gitignore
├── LICENSE
├── MANIFEST.in
├── README
├── README.markdown
├── docs
├── Makefile
├── _ext
│ ├── djangodocs.py
│ └── philodocs.py
├── cla
│ ├── ithinksw-ccla.txt
│ └── ithinksw-icla.txt
├── conf.py
├── contrib
│ ├── intro.rst
│ ├── penfield.rst
│ ├── shipherd.rst
│ ├── sobol.rst
│ ├── waldo.rst
│ └── winer.rst
├── contributing.rst
├── dummy-settings.py
├── exceptions.rst
├── forms.rst
├── handling_requests.rst
├── index.rst
├── loaders.rst
├── make.bat
├── models
│ ├── collections.rst
│ ├── entities.rst
│ ├── fields.rst
│ ├── intro.rst
│ ├── miscellaneous.rst
│ └── nodes-and-views.rst
├── releases
│ ├── 0.9.1.rst
│ └── 0.9.2.rst
├── signals.rst
├── templatetags.rst
├── tutorials
│ ├── getting-started.rst
│ ├── intro.rst
│ └── shipherd.rst
├── utilities.rst
├── validators.rst
└── what.rst
├── philo
├── __init__.py
├── admin
│ ├── __init__.py
│ ├── base.py
│ ├── collections.py
│ ├── forms
│ │ ├── __init__.py
│ │ ├── attributes.py
│ │ └── containers.py
│ ├── nodes.py
│ ├── pages.py
│ └── widgets.py
├── contrib
│ ├── __init__.py
│ ├── julian
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── feedgenerator.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ └── models.py
│ ├── penfield
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_auto.py
│ │ │ ├── 0003_auto__add_field_newsletterview_feed_type__add_field_newsletterview_ite.py
│ │ │ ├── 0004_auto__add_field_newsletterview_feed_length__add_field_blogview_feed_le.py
│ │ │ ├── 0005_to_taggit.py
│ │ │ ├── 0006_delete_tag_rels.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ └── templatetags
│ │ │ ├── __init__.py
│ │ │ └── penfield.py
│ ├── shipherd
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ ├── 0002_auto.py
│ │ │ ├── 0003_auto__del_field_navigationitem_slug.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ └── templatetags
│ │ │ ├── __init__.py
│ │ │ └── shipherd.py
│ ├── sobol
│ │ ├── __init__.py
│ │ ├── admin.py
│ │ ├── forms.py
│ │ ├── migrations
│ │ │ ├── 0001_initial.py
│ │ │ └── __init__.py
│ │ ├── models.py
│ │ ├── search.py
│ │ ├── static
│ │ │ └── sobol
│ │ │ │ └── ajax_search.js
│ │ ├── templates
│ │ │ ├── admin
│ │ │ │ └── sobol
│ │ │ │ │ └── search
│ │ │ │ │ ├── change_form.html
│ │ │ │ │ ├── change_list.html
│ │ │ │ │ └── grappelli_change_form.html
│ │ │ └── sobol
│ │ │ │ └── search
│ │ │ │ ├── _list.html
│ │ │ │ ├── content.html
│ │ │ │ └── result.html
│ │ └── utils.py
│ ├── waldo
│ │ ├── __init__.py
│ │ ├── forms.py
│ │ ├── models.py
│ │ └── tokens.py
│ └── winer
│ │ ├── __init__.py
│ │ ├── exceptions.py
│ │ ├── feeds.py
│ │ ├── middleware.py
│ │ └── models.py
├── exceptions.py
├── fixtures
│ └── test_fixtures.json
├── forms
│ ├── __init__.py
│ ├── entities.py
│ └── fields.py
├── loaders
│ ├── __init__.py
│ └── database.py
├── middleware.py
├── migrations
│ ├── 0001_initial.py
│ ├── 0002_auto__add_field_attribute_value.py
│ ├── 0003_move_json.py
│ ├── 0004_auto__del_field_attribute_json_value.py
│ ├── 0005_add_attribute_values.py
│ ├── 0006_move_attribute_and_relationship_values.py
│ ├── 0007_auto__del_relationship__del_field_attribute_value.py
│ ├── 0008_auto__del_field_manytomanyvalue_object_ids.py
│ ├── 0009_auto__add_field_node_lft__add_field_node_rght__add_field_node_tree_id_.py
│ ├── 0010_auto__add_field_redirect_target_node__add_field_redirect_url_or_subpat.py
│ ├── 0011_move_target_url.py
│ ├── 0012_auto__del_field_redirect_target.py
│ ├── 0013_auto.py
│ ├── 0014_auto.py
│ ├── 0015_auto__add_unique_node_slug_parent__add_unique_template_slug_parent.py
│ ├── 0016_auto__add_field_file_name.py
│ ├── 0017_generate_filenames.py
│ ├── 0018_auto__chg_field_node_view_object_id__chg_field_node_view_content_type.py
│ ├── 0019_to_taggit.py
│ ├── 0020_from_taggit.py
│ ├── 0021_auto__del_tag.py
│ └── __init__.py
├── models
│ ├── __init__.py
│ ├── base.py
│ ├── collections.py
│ ├── fields
│ │ ├── __init__.py
│ │ └── entities.py
│ ├── nodes.py
│ └── pages.py
├── signals.py
├── static
│ └── philo
│ │ ├── css
│ │ └── EmbedWidget.css
│ │ └── js
│ │ └── EmbedWidget.js
├── templates
│ └── admin
│ │ └── philo
│ │ ├── edit_inline
│ │ ├── grappelli_tabular_attribute.html
│ │ ├── grappelli_tabular_container.html
│ │ ├── tabular_attribute.html
│ │ └── tabular_container.html
│ │ └── page
│ │ └── add_form.html
├── templatetags
│ ├── __init__.py
│ ├── collections.py
│ ├── containers.py
│ ├── embed.py
│ ├── include_string.py
│ └── nodes.py
├── tests.py
├── urls.py
├── utils
│ ├── __init__.py
│ ├── entities.py
│ ├── lazycompat.py
│ ├── registry.py
│ └── templates.py
├── validators.py
└── views.py
└── setup.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 | docs/_build/
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2009-2012, iThink Software.
2 |
3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
4 |
5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
6 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include README
2 | include README.markdown
3 | include LICENSE
4 | include MANIFEST.in
5 | recursive-include philo/templates *.html
6 | recursive-include philo/contrib/sobol/templates *.html
7 | recursive-include philo/fixtures *.json
8 | recursive-include philo/static *.css *.js
9 | recursive-include philo/contrib/sobol/static *.css *.js
10 | recursive-include docs *.py *.rst *.bat *.txt Makefile
11 | global-exclude *~
12 | prune docs/_build
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | Philo is a foundation for developing web content management systems.
2 |
3 | Prerequisites:
4 | * Python 2.5.4+
5 | * Django 1.3+
6 | * django-mptt e734079+
7 | * (optional) django-grappelli 2.0+
8 | * (optional) south 0.7.2+
9 | * (philo.contrib.penfield) django-taggit 0.9.3+
10 | * (philo.contrib.waldo, optional) recaptcha-django r6+
11 |
12 | After installing philo and mptt on your PYTHONPATH, make sure to complete the following steps:
13 |
14 | 1. Add 'philo.middleware.RequestNodeMiddleware' to settings.MIDDLEWARE_CLASSES.
15 | 2. Add 'philo' and 'mptt' to settings.INSTALLED_APPS.
16 | 3. Include 'philo.urls' somewhere in your urls.py file.
17 | 4. Optionally add a root node to your current Site.
18 |
19 | Philo should be ready to go! All that's left is to learn more and contribute .
20 |
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | [Philo](http://philocms.org/) is a foundation for developing web content management systems.
2 |
3 | Prerequisites:
4 |
5 | * [Python 2.5.4+](http://www.python.org/)
6 | * [Django 1.3+](http://www.djangoproject.com/)
7 | * [django-mptt e734079+](https://github.com/django-mptt/django-mptt/)
8 | * (optional) [django-grappelli 2.0+](http://code.google.com/p/django-grappelli/)
9 | * (optional) [south 0.7.2+](http://south.aeracode.org/)
10 | * (philo.contrib.penfield) [django-taggit 0.9.3+](https://github.com/alex/django-taggit/)
11 | * (philo.contrib.waldo, optional) [recaptcha-django r6+](http://code.google.com/p/recaptcha-django/)
12 |
13 | After installing philo and mptt on your PYTHONPATH, make sure to complete the following steps:
14 |
15 | 1. Add 'philo.middleware.RequestNodeMiddleware' to settings.MIDDLEWARE_CLASSES.
16 | 2. Add 'philo' and 'mptt' to settings.INSTALLED_APPS.
17 | 3. Include 'philo.urls' somewhere in your urls.py file.
18 | 4. Optionally add a root node to your current Site.
19 |
20 | Philo should be ready to go! All that's left is to [learn more](http://docs.philocms.org/) and [contribute](http://docs.philocms.org/en/latest/contribute.html).
21 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = _build
9 |
10 | # Internal variables.
11 | PAPEROPT_a4 = -D latex_paper_size=a4
12 | PAPEROPT_letter = -D latex_paper_size=letter
13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
14 |
15 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
16 |
17 | help:
18 | @echo "Please use \`make ' where is one of"
19 | @echo " html to make standalone HTML files"
20 | @echo " dirhtml to make HTML files named index.html in directories"
21 | @echo " singlehtml to make a single large HTML file"
22 | @echo " pickle to make pickle files"
23 | @echo " json to make JSON files"
24 | @echo " htmlhelp to make HTML files and a HTML help project"
25 | @echo " qthelp to make HTML files and a qthelp project"
26 | @echo " devhelp to make HTML files and a Devhelp project"
27 | @echo " epub to make an epub"
28 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
29 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
30 | @echo " text to make text files"
31 | @echo " man to make manual pages"
32 | @echo " changes to make an overview of all changed/added/deprecated items"
33 | @echo " linkcheck to check all external links for integrity"
34 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
35 |
36 | clean:
37 | -rm -rf $(BUILDDIR)/*
38 |
39 | html:
40 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
41 | @echo
42 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
43 |
44 | dirhtml:
45 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
46 | @echo
47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
48 |
49 | singlehtml:
50 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
51 | @echo
52 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
53 |
54 | pickle:
55 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
56 | @echo
57 | @echo "Build finished; now you can process the pickle files."
58 |
59 | json:
60 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
61 | @echo
62 | @echo "Build finished; now you can process the JSON files."
63 |
64 | htmlhelp:
65 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
66 | @echo
67 | @echo "Build finished; now you can run HTML Help Workshop with the" \
68 | ".hhp project file in $(BUILDDIR)/htmlhelp."
69 |
70 | qthelp:
71 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
72 | @echo
73 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
74 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
75 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Philo.qhcp"
76 | @echo "To view the help file:"
77 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Philo.qhc"
78 |
79 | devhelp:
80 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
81 | @echo
82 | @echo "Build finished."
83 | @echo "To view the help file:"
84 | @echo "# mkdir -p $$HOME/.local/share/devhelp/Philo"
85 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Philo"
86 | @echo "# devhelp"
87 |
88 | epub:
89 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
90 | @echo
91 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
92 |
93 | latex:
94 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
95 | @echo
96 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
97 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
98 | "(use \`make latexpdf' here to do that automatically)."
99 |
100 | latexpdf:
101 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
102 | @echo "Running LaTeX files through pdflatex..."
103 | make -C $(BUILDDIR)/latex all-pdf
104 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
105 |
106 | text:
107 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
108 | @echo
109 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
110 |
111 | man:
112 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
113 | @echo
114 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
115 |
116 | changes:
117 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
118 | @echo
119 | @echo "The overview file is in $(BUILDDIR)/changes."
120 |
121 | linkcheck:
122 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
123 | @echo
124 | @echo "Link check complete; look for any errors in the above output " \
125 | "or in $(BUILDDIR)/linkcheck/output.txt."
126 |
127 | doctest:
128 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
129 | @echo "Testing of doctests in the sources finished, look at the " \
130 | "results in $(BUILDDIR)/doctest/output.txt."
131 |
--------------------------------------------------------------------------------
/docs/_ext/philodocs.py:
--------------------------------------------------------------------------------
1 | import inspect
2 |
3 | from sphinx.addnodes import desc_addname
4 | from sphinx.domains.python import PyModulelevel, PyXRefRole
5 | from sphinx.ext import autodoc
6 |
7 |
8 | DOMAIN = 'py'
9 |
10 |
11 | class TemplateTag(PyModulelevel):
12 | indextemplate = "pair: %s; template tag"
13 |
14 | def get_signature_prefix(self, sig):
15 | return self.objtype + ' '
16 |
17 | def handle_signature(self, sig, signode):
18 | fullname, name_prefix = PyModulelevel.handle_signature(self, sig, signode)
19 |
20 | for i, node in enumerate(signode):
21 | if isinstance(node, desc_addname):
22 | lib = '.'.join(node[0].split('.')[-2:])
23 | new_node = desc_addname(lib, lib)
24 | signode[i] = new_node
25 |
26 | return fullname, name_prefix
27 |
28 |
29 | class TemplateTagDocumenter(autodoc.FunctionDocumenter):
30 | objtype = 'templatetag'
31 | domain = DOMAIN
32 |
33 | @classmethod
34 | def can_document_member(cls, member, membername, isattr, parent):
35 | # Only document explicitly.
36 | return False
37 |
38 | def format_args(self):
39 | return None
40 |
41 | class TemplateFilterDocumenter(autodoc.FunctionDocumenter):
42 | objtype = 'templatefilter'
43 | domain = DOMAIN
44 |
45 | @classmethod
46 | def can_document_member(cls, member, membername, isattr, parent):
47 | # Only document explicitly.
48 | return False
49 |
50 | def setup(app):
51 | app.add_directive_to_domain(DOMAIN, 'templatetag', TemplateTag)
52 | app.add_role_to_domain(DOMAIN, 'ttag', PyXRefRole())
53 | app.add_directive_to_domain(DOMAIN, 'templatefilter', TemplateTag)
54 | app.add_role_to_domain(DOMAIN, 'tfilter', PyXRefRole())
55 | app.add_autodocumenter(TemplateTagDocumenter)
56 | app.add_autodocumenter(TemplateFilterDocumenter)
--------------------------------------------------------------------------------
/docs/cla/ithinksw-icla.txt:
--------------------------------------------------------------------------------
1 | iThink Software
2 | Individual Contributor License Agreement ("Agreement") v1.0.1
3 |
4 | Thank you for your interest in iThink Software. In order to clarify
5 | the intellectual property license granted with Contributions from
6 | any person or entity, iThink Software must have a Contributor
7 | License Agreement ("CLA") on file that has been signed by each
8 | Contributor, indicating agreement to the license terms below. This
9 | license is for your protection as a Contributor as well as the
10 | protection of iThink Software and its users; it does not change
11 | your rights to use your own Contributions for any other purpose.
12 | If you have not already done so, please complete and sign, then scan
13 | and email a pdf file of this Agreement to contact@ithinksw.com.
14 | Alternatively, you may send an original signed Agreement to
15 | iThink Software, 261 West Lorain Street, Oberlin, OH 44074, U.S.A.
16 | Please read this document carefully before signing and
17 | keep a copy for your records.
18 |
19 | Full name: ______________________________________________________
20 |
21 | Mailing Address: ________________________________________________
22 |
23 | _________________________________________________________________
24 |
25 | Country: ______________________________________________________
26 |
27 | Telephone: ______________________________________________________
28 |
29 | Facsimile: ______________________________________________________
30 |
31 | E-Mail: ______________________________________________________
32 |
33 | You accept and agree to the following terms and conditions for Your
34 | present and future Contributions submitted to iThink Software. Except
35 | for the license granted herein to iThink Software and recipients of
36 | software distributed by iThink Software, You reserve all right,
37 | title, and interest in and to Your Contributions.
38 |
39 | 1. Definitions.
40 |
41 | "You" (or "Your") shall mean the copyright owner or legal entity
42 | authorized by the copyright owner that is making this Agreement
43 | with iThink Software. For legal entities, the entity making a
44 | Contribution and all other entities that control, are controlled
45 | by, or are under common control with that entity are considered to
46 | be a single Contributor. For the purposes of this definition,
47 | "control" means (i) the power, direct or indirect, to cause the
48 | direction or management of such entity, whether by contract or
49 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
50 | outstanding shares, or (iii) beneficial ownership of such entity.
51 |
52 | "Contribution" shall mean any original work of authorship,
53 | including any modifications or additions to an existing work, that
54 | is intentionally submitted by You to iThink Software for inclusion
55 | in, or documentation of, any of the products owned or managed by
56 | iThink Software (the "Work"). For the purposes of this definition,
57 | "submitted" means any form of electronic, verbal, or written
58 | communication sent to iThink Software or its representatives,
59 | including but not limited to communication on electronic mailing
60 | lists, source code control systems, and issue tracking systems that
61 | are managed by, or on behalf of, iThink Software for the purpose of
62 | discussing and improving the Work, but excluding communication that
63 | is conspicuously marked or otherwise designated in writing by You
64 | as "Not a Contribution."
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this Agreement, You hereby grant to iThink Software and to
68 | recipients of software distributed by iThink Software a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare derivative works of,
71 | publicly display, publicly perform, sublicense, and distribute Your
72 | Contributions and such derivative works.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this Agreement, You hereby grant to iThink Software and to
76 | recipients of software distributed by iThink Software a perpetual,
77 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
78 | (except as stated in this section) patent license to make, have
79 | made, use, offer to sell, sell, import, and otherwise transfer the
80 | Work, where such license applies only to those patent claims
81 | licensable by You that are necessarily infringed by Your
82 | Contribution(s) alone or by combination of Your Contribution(s)
83 | with the Work to which such Contribution(s) were submitted. If any
84 | entity institutes patent litigation against You or any other entity
85 | (including a cross-claim or counterclaim in a lawsuit) alleging
86 | that your Contribution, or the Work to which you have contributed,
87 | constitutes direct or contributory patent infringement, then any
88 | patent licenses granted to that entity under this Agreement for
89 | that Contribution or Work shall terminate as of the date such
90 | litigation is filed.
91 |
92 | 4. You represent that you are legally entitled to grant the above
93 | license. If your employer(s) has rights to intellectual property
94 | that you create that includes your Contributions, you represent
95 | that you have received permission to make Contributions on behalf
96 | of that employer, that your employer has waived such rights for
97 | your Contributions to iThink Software, or that your employer has
98 | executed a separate Corporate CLA with iThink Software.
99 |
100 | 5. You represent that each of Your Contributions is Your original
101 | creation (see section 7 for submissions on behalf of others). You
102 | represent that Your Contribution submissions include complete
103 | details of any third-party license or other restriction (including,
104 | but not limited to, related patents and trademarks) of which you
105 | are personally aware and which are associated with any part of Your
106 | Contributions.
107 |
108 | 6. You are not expected to provide support for Your Contributions,
109 | except to the extent You desire to provide support. You may provide
110 | support for free, for a fee, or not at all. Unless required by
111 | applicable law or agreed to in writing, You provide Your
112 | Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
113 | OF ANY KIND, either express or implied, including, without
114 | limitation, any warranties or conditions of TITLE, NON-
115 | INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
116 |
117 | 7. Should You wish to submit work that is not Your original creation,
118 | You may submit it to iThink Software separately from any
119 | Contribution, identifying the complete details of its source and of
120 | any license or other restriction (including, but not limited to,
121 | related patents, trademarks, and license agreements) of which you
122 | are personally aware, and conspicuously marking the work as
123 | "Submitted on behalf of a third-party: [named here]".
124 |
125 | 8. You agree to notify iThink Software of any facts or circumstances of
126 | which you become aware that would make these representations
127 | inaccurate in any respect.
128 |
129 |
130 | Please sign: __________________________________ Date: ________________
131 |
--------------------------------------------------------------------------------
/docs/contrib/intro.rst:
--------------------------------------------------------------------------------
1 | Contrib apps
2 | ============
3 |
4 | .. toctree::
5 | :maxdepth: 2
6 | :hidden:
7 |
8 | penfield
9 | shipherd
10 | sobol
11 | waldo
12 | winer
13 |
14 | .. automodule:: philo.contrib
15 |
--------------------------------------------------------------------------------
/docs/contrib/penfield.rst:
--------------------------------------------------------------------------------
1 | Penfield
2 | ========
3 |
4 | .. automodule:: philo.contrib.penfield
5 |
6 | .. automodule:: philo.contrib.penfield.models
7 |
8 | Blogs
9 | +++++
10 | .. autoclass:: philo.contrib.penfield.models.Blog
11 | :members:
12 |
13 | .. autoclass:: philo.contrib.penfield.models.BlogEntry
14 | :members:
15 |
16 | .. autoclass:: philo.contrib.penfield.models.BlogView
17 | :members:
18 |
19 | Newsletters
20 | +++++++++++
21 | .. autoclass:: philo.contrib.penfield.models.Newsletter
22 | :members:
23 |
24 | .. autoclass:: philo.contrib.penfield.models.NewsletterArticle
25 | :members:
26 |
27 | .. autoclass:: philo.contrib.penfield.models.NewsletterView
28 | :members:
29 |
30 | Template filters
31 | ++++++++++++++++
32 |
33 | .. automodule:: philo.contrib.penfield.templatetags.penfield
34 |
35 | .. autotemplatefilter:: monthname
36 |
37 | .. autotemplatefilter:: apmonthname
38 |
--------------------------------------------------------------------------------
/docs/contrib/shipherd.rst:
--------------------------------------------------------------------------------
1 | Shipherd
2 | ========
3 |
4 | .. automodule:: philo.contrib.shipherd
5 | :members:
6 |
7 | :class:`.Node`\ s are useful for structuring a website; however, they are inherently unsuitable for creating site navigation.
8 |
9 | The most glaring problem is that a navigation tree based on :class:`.Node`\ s would have one :class:`.Node` as the root, whereas navigation usually has multiple objects at the top level.
10 |
11 | Additionally, navigation needs to have display text that is relevant to the current context; however, :class:`.Node`\ s do not have a field for that, and :class:`.View` subclasses with a name or title field will generally need to use it for database-searchable names.
12 |
13 | Finally, :class:`.Node` structures are inherently unordered, while navigation is inherently ordered.
14 |
15 | :mod:`~philo.contrib.shipherd` exists to resolve these issues by separating navigation structures from :class:`.Node` structures. It is instead structured around the way that site navigation works in the wild:
16 |
17 | * A site may have one or more independent navigation bars (Main navigation, side navigation, etc.)
18 | * A navigation bar may be shared by sections of the website, or even by the entire site.
19 | * A navigation bar has a certain depth that it displays to.
20 |
21 | The :class:`.Navigation` model supplies these features by attaching itself to a :class:`.Node` via :class:`ForeignKey` and adding a :attr:`navigation` property to :class:`.Node` which provides access to a :class:`.Node` instance's inherited :class:`.Navigation`\ s.
22 |
23 | Each entry in the navigation bar is then represented by a :class:`.NavigationItem`, which stores information such as the :attr:`~.NavigationItem.order` and :attr:`~.NavigationItem.text` for the entry. Given an :class:`HttpRequest`, a :class:`.NavigationItem` can also tell whether it :meth:`~.NavigationItem.is_active` or :meth:`~.NavigationItem.has_active_descendants`.
24 |
25 | Since the common pattern is to recurse through a navigation tree and render each part similarly, :mod:`~philo.contrib.shipherd` also ships with the :ttag:`~philo.contrib.shipherd.templatetags.shipherd.recursenavigation` template tag.
26 |
27 | Models
28 | ++++++
29 |
30 | .. automodule:: philo.contrib.shipherd.models
31 | :members: Navigation, NavigationItem, NavigationMapper
32 | :show-inheritance:
33 |
34 | .. autoclass:: NavigationManager
35 | :members:
36 |
37 | Template tags
38 | +++++++++++++
39 |
40 | .. automodule:: philo.contrib.shipherd.templatetags.shipherd
41 |
42 | .. autotemplatetag:: recursenavigation
43 |
44 | .. autotemplatefilter:: has_navigation
45 |
46 | .. autotemplatefilter:: navigation_host
47 |
--------------------------------------------------------------------------------
/docs/contrib/sobol.rst:
--------------------------------------------------------------------------------
1 | Sobol
2 | =====
3 |
4 | .. automodule:: philo.contrib.sobol
5 | :members:
6 |
7 | Models
8 | ++++++
9 |
10 | .. automodule:: philo.contrib.sobol.models
11 | :members:
12 |
13 | Search API
14 | ++++++++++
15 |
16 | .. automodule:: philo.contrib.sobol.search
17 | :members:
18 |
--------------------------------------------------------------------------------
/docs/contrib/waldo.rst:
--------------------------------------------------------------------------------
1 | Waldo
2 | =====
3 |
4 | .. automodule:: philo.contrib.waldo
5 | :members:
6 |
7 | Models
8 | ++++++
9 |
10 | .. automodule:: philo.contrib.waldo.models
11 | :members:
12 |
13 | Forms
14 | +++++
15 |
16 | .. automodule:: philo.contrib.waldo.forms
17 | :members:
18 |
19 | Token generators
20 | ++++++++++++++++
21 |
22 | .. automodule:: philo.contrib.waldo.tokens
23 |
24 |
25 | .. autodata:: registration_token_generator
26 |
27 | .. autodata:: email_token_generator
28 |
--------------------------------------------------------------------------------
/docs/contrib/winer.rst:
--------------------------------------------------------------------------------
1 | Winer
2 | =====
3 |
4 | .. automodule:: philo.contrib.winer
5 |
6 | .. automodule:: philo.contrib.winer.models
7 |
8 | .. autoclass:: FeedView
9 | :members:
10 |
11 | .. automodule:: philo.contrib.winer.exceptions
12 | :members:
13 |
14 | .. automodule:: philo.contrib.winer.middleware
15 | :members:
--------------------------------------------------------------------------------
/docs/contributing.rst:
--------------------------------------------------------------------------------
1 | Contributing to Philo
2 | =====================
3 |
4 | So you want to contribute to Philo? That's great! Here's some ways you can get started:
5 |
6 | * **Report bugs and request features** using the issue tracker at the `project site `_.
7 | * **Contribute code** using `git `_. You can fork philo's repository either on `GitHub `_ or `Gitorious `_. If you are contributing to Philo, you will need to submit a :ref:`Contributor License Agreement `.
8 | * **Join the discussion** on IRC at `irc://irc.oftc.net/#philo `_ if you have any questions or suggestions or just want to chat about the project. You can also keep in touch using the project mailing lists: `philo@ithinksw.org `_ and `philo-devel@ithinksw.org `_.
9 |
10 |
11 | Branches and Code Style
12 | +++++++++++++++++++++++
13 |
14 | We use `A successful Git branching model`__ with the blessed repository. To make things easier, you probably should too. This means that you should work on and against the develop branch in most cases, and leave it to the release manager to create the commits on the master branch if and when necessary. When pulling changes into the blessed repository at your request, the release manager will usually merge them into the develop branch unless you explicitly note they be treated otherwise.
15 |
16 | __ http://nvie.com/posts/a-successful-git-branching-model/
17 |
18 | Philo adheres to PEP8 for its code style, with two exceptions: tabs are used rather than spaces, and lines are not truncated at 79 characters.
19 |
20 | .. _cla:
21 |
22 | Licensing and Legal
23 | +++++++++++++++++++
24 |
25 | In order for the release manager to merge your changes into the blessed repository, you will need to have already submitted a signed CLA. Our CLAs are based on the Apache Software Foundation's CLAs, which is the same source as the `Django Project's CLAs`_. You might, therefore, find the `Django Project's CLA FAQ`_. helpful.
26 |
27 | .. _`Django Project's CLAs`: https://www.djangoproject.com/foundation/cla/
28 | .. _`Django Project's CLA FAQ`: https://www.djangoproject.com/foundation/cla/faq/
29 |
30 | If you are an individual not doing work for an employer, then you can simply submit the :download:`Individual CLA `.
31 |
32 | If you are doing work for an employer, they will need to submit the :download:`Corporate CLA ` and you will need to submit the Individual CLA :download:`Individual CLA ` as well.
33 |
34 | Both documents include information on how to submit them.
35 |
--------------------------------------------------------------------------------
/docs/dummy-settings.py:
--------------------------------------------------------------------------------
1 | DATABASES = {
2 | 'default': {
3 | 'ENGINE': 'django.db.backends.sqlite3',
4 | 'NAME': 'db.sl3'
5 | }
6 | }
--------------------------------------------------------------------------------
/docs/exceptions.rst:
--------------------------------------------------------------------------------
1 | Exceptions
2 | ==========
3 |
4 | .. automodule:: philo.exceptions
5 | :members: MIDDLEWARE_NOT_CONFIGURED, AncestorDoesNotExist, ViewCanNotProvideSubpath, ViewDoesNotProvideSubpaths
--------------------------------------------------------------------------------
/docs/forms.rst:
--------------------------------------------------------------------------------
1 | Forms
2 | =====
3 |
4 | .. automodule:: philo.forms.entities
5 | :members:
6 |
7 |
8 | Fields
9 | ++++++
10 |
11 | .. automodule:: philo.forms.fields
12 | :members:
13 |
--------------------------------------------------------------------------------
/docs/handling_requests.rst:
--------------------------------------------------------------------------------
1 | Handling Requests
2 | =================
3 |
4 | .. automodule:: philo.middleware
5 | :members:
6 |
7 | .. automodule:: philo.views
8 |
9 |
10 | .. autofunction:: node_view(request[, path=None, **kwargs])
11 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. Philo documentation master file, created by
2 | sphinx-quickstart on Fri Jan 28 14:04:16 2011.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | .. module:: philo
7 |
8 | Welcome to Philo's documentation!
9 | =================================
10 |
11 | Philo is a foundation for developing web content management systems. Please, read the :doc:`notes for our latest release `.
12 |
13 | Prerequisites:
14 |
15 | * `Python 2.5.4+ `_
16 | * `Django 1.3+ `_
17 | * `django-mptt e734079+ `_
18 | * (optional) `django-grappelli 2.0+ `_
19 | * (optional) `south 0.7.2+ `_
20 | * (:mod:`philo.contrib.penfield`) `django-taggit 0.9.3+ `_
21 | * (:mod:`philo.contrib.waldo`, optional) `recaptcha-django r6+ `_
22 |
23 | Contents
24 | ++++++++
25 |
26 | .. toctree::
27 | :maxdepth: 1
28 |
29 | what
30 | tutorials/intro
31 | models/intro
32 | exceptions
33 | handling_requests
34 | signals
35 | validators
36 | utilities
37 | templatetags
38 | forms
39 | loaders
40 | contrib/intro
41 | contributing
42 |
43 | Indices and tables
44 | ++++++++++++++++++
45 |
46 | * :ref:`genindex`
47 | * :ref:`modindex`
48 | * :ref:`search`
49 |
--------------------------------------------------------------------------------
/docs/loaders.rst:
--------------------------------------------------------------------------------
1 | Database Template Loader
2 | ========================
3 |
4 | .. automodule:: philo.loaders.database
5 | :members:
6 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | if "%SPHINXBUILD%" == "" (
6 | set SPHINXBUILD=sphinx-build
7 | )
8 | set BUILDDIR=_build
9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
10 | if NOT "%PAPER%" == "" (
11 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
12 | )
13 |
14 | if "%1" == "" goto help
15 |
16 | if "%1" == "help" (
17 | :help
18 | echo.Please use `make ^` where ^ is one of
19 | echo. html to make standalone HTML files
20 | echo. dirhtml to make HTML files named index.html in directories
21 | echo. singlehtml to make a single large HTML file
22 | echo. pickle to make pickle files
23 | echo. json to make JSON files
24 | echo. htmlhelp to make HTML files and a HTML help project
25 | echo. qthelp to make HTML files and a qthelp project
26 | echo. devhelp to make HTML files and a Devhelp project
27 | echo. epub to make an epub
28 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
29 | echo. text to make text files
30 | echo. man to make manual pages
31 | echo. changes to make an overview over all changed/added/deprecated items
32 | echo. linkcheck to check all external links for integrity
33 | echo. doctest to run all doctests embedded in the documentation if enabled
34 | goto end
35 | )
36 |
37 | if "%1" == "clean" (
38 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
39 | del /q /s %BUILDDIR%\*
40 | goto end
41 | )
42 |
43 | if "%1" == "html" (
44 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
45 | if errorlevel 1 exit /b 1
46 | echo.
47 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
48 | goto end
49 | )
50 |
51 | if "%1" == "dirhtml" (
52 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
53 | if errorlevel 1 exit /b 1
54 | echo.
55 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
56 | goto end
57 | )
58 |
59 | if "%1" == "singlehtml" (
60 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
61 | if errorlevel 1 exit /b 1
62 | echo.
63 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
64 | goto end
65 | )
66 |
67 | if "%1" == "pickle" (
68 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
69 | if errorlevel 1 exit /b 1
70 | echo.
71 | echo.Build finished; now you can process the pickle files.
72 | goto end
73 | )
74 |
75 | if "%1" == "json" (
76 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
77 | if errorlevel 1 exit /b 1
78 | echo.
79 | echo.Build finished; now you can process the JSON files.
80 | goto end
81 | )
82 |
83 | if "%1" == "htmlhelp" (
84 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
85 | if errorlevel 1 exit /b 1
86 | echo.
87 | echo.Build finished; now you can run HTML Help Workshop with the ^
88 | .hhp project file in %BUILDDIR%/htmlhelp.
89 | goto end
90 | )
91 |
92 | if "%1" == "qthelp" (
93 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
94 | if errorlevel 1 exit /b 1
95 | echo.
96 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
97 | .qhcp project file in %BUILDDIR%/qthelp, like this:
98 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Philo.qhcp
99 | echo.To view the help file:
100 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Philo.ghc
101 | goto end
102 | )
103 |
104 | if "%1" == "devhelp" (
105 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
106 | if errorlevel 1 exit /b 1
107 | echo.
108 | echo.Build finished.
109 | goto end
110 | )
111 |
112 | if "%1" == "epub" (
113 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
114 | if errorlevel 1 exit /b 1
115 | echo.
116 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
117 | goto end
118 | )
119 |
120 | if "%1" == "latex" (
121 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
122 | if errorlevel 1 exit /b 1
123 | echo.
124 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
125 | goto end
126 | )
127 |
128 | if "%1" == "text" (
129 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
130 | if errorlevel 1 exit /b 1
131 | echo.
132 | echo.Build finished. The text files are in %BUILDDIR%/text.
133 | goto end
134 | )
135 |
136 | if "%1" == "man" (
137 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
138 | if errorlevel 1 exit /b 1
139 | echo.
140 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
141 | goto end
142 | )
143 |
144 | if "%1" == "changes" (
145 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
146 | if errorlevel 1 exit /b 1
147 | echo.
148 | echo.The overview file is in %BUILDDIR%/changes.
149 | goto end
150 | )
151 |
152 | if "%1" == "linkcheck" (
153 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
154 | if errorlevel 1 exit /b 1
155 | echo.
156 | echo.Link check complete; look for any errors in the above output ^
157 | or in %BUILDDIR%/linkcheck/output.txt.
158 | goto end
159 | )
160 |
161 | if "%1" == "doctest" (
162 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
163 | if errorlevel 1 exit /b 1
164 | echo.
165 | echo.Testing of doctests in the sources finished, look at the ^
166 | results in %BUILDDIR%/doctest/output.txt.
167 | goto end
168 | )
169 |
170 | :end
171 |
--------------------------------------------------------------------------------
/docs/models/collections.rst:
--------------------------------------------------------------------------------
1 | Collections
2 | ===========
3 |
4 | .. automodule:: philo.models.collections
5 | :members: Collection, CollectionMember, CollectionMemberManager
6 |
7 | .. autoclass:: CollectionMemberManager
8 | :members:
--------------------------------------------------------------------------------
/docs/models/entities.rst:
--------------------------------------------------------------------------------
1 | Entities and Attributes
2 | =======================
3 |
4 | .. module:: philo.models.base
5 |
6 | One of the core concepts in Philo is the relationship between the :class:`Entity` and :class:`Attribute` classes. :class:`Attribute`\ s represent an arbitrary key/value pair by having one :class:`GenericForeignKey` to an :class:`Entity` and another to an :class:`AttributeValue`.
7 |
8 |
9 | Attributes
10 | ----------
11 |
12 | .. autoclass:: Attribute
13 | :members:
14 |
15 | .. autoclass:: AttributeValue
16 | :members:
17 |
18 | .. automodule:: philo.models.base
19 | :noindex:
20 | :members: attribute_value_limiter
21 |
22 | .. autoclass:: JSONValue
23 | :show-inheritance:
24 |
25 | .. autoclass:: ForeignKeyValue
26 | :show-inheritance:
27 |
28 | .. autoclass:: ManyToManyValue
29 | :show-inheritance:
30 |
31 | .. automodule:: philo.models.base
32 | :noindex:
33 | :members: value_content_type_limiter
34 |
35 | .. autofunction:: register_value_model(model)
36 | .. autofunction:: unregister_value_model(model)
37 |
38 | Entities
39 | --------
40 |
41 | .. autoclass:: Entity
42 | :members:
43 |
44 | .. autoclass:: TreeEntityManager
45 | :members:
46 |
47 | .. autoclass:: TreeEntity
48 | :show-inheritance:
49 | :members:
50 |
51 | .. attribute:: objects
52 |
53 | An instance of :class:`TreeEntityManager`.
54 |
55 | .. automethod:: get_path
--------------------------------------------------------------------------------
/docs/models/fields.rst:
--------------------------------------------------------------------------------
1 | Custom Fields
2 | =============
3 |
4 | .. automodule:: philo.models.fields
5 | :members:
6 | :exclude-members: JSONField, SlugMultipleChoiceField
7 |
8 | .. autoclass:: JSONField()
9 | :members:
10 |
11 | .. autoclass:: SlugMultipleChoiceField()
12 | :members:
13 |
14 | AttributeProxyFields
15 | --------------------
16 |
17 | .. automodule:: philo.models.fields.entities
18 | :members:
19 |
20 | .. autoclass:: AttributeProxyField(attribute_key=None, verbose_name=None, help_text=None, default=NOT_PROVIDED, editable=True, choices=None, *args, **kwargs)
21 | :members:
--------------------------------------------------------------------------------
/docs/models/intro.rst:
--------------------------------------------------------------------------------
1 | Philo's models
2 | ==============
3 |
4 | Contents:
5 |
6 | .. toctree::
7 | :maxdepth: 2
8 |
9 | entities
10 | nodes-and-views
11 | collections
12 | miscellaneous
13 | fields
14 |
15 |
16 | .. automodule:: philo.models
17 |
--------------------------------------------------------------------------------
/docs/models/miscellaneous.rst:
--------------------------------------------------------------------------------
1 | Miscellaneous Models
2 | =============================
3 | .. autoclass:: philo.models.nodes.TargetURLModel
4 | :members:
5 | :exclude-members: get_target_url
--------------------------------------------------------------------------------
/docs/models/nodes-and-views.rst:
--------------------------------------------------------------------------------
1 | Nodes and Views: Building Website structure
2 | ===========================================
3 | .. automodule:: philo.models.nodes
4 |
5 | Nodes
6 | -----
7 |
8 | .. autoclass:: Node
9 | :show-inheritance:
10 | :members:
11 |
12 | Views
13 | -----
14 |
15 | Abstract View Models
16 | ++++++++++++++++++++
17 |
18 | .. autoclass:: View
19 | :show-inheritance:
20 | :members:
21 |
22 | .. autoclass:: MultiView
23 | :show-inheritance:
24 | :members:
25 |
26 | Concrete View Subclasses
27 | ++++++++++++++++++++++++
28 |
29 | .. autoclass:: Redirect
30 | :show-inheritance:
31 | :members:
32 |
33 | .. autoclass:: File
34 | :show-inheritance:
35 | :members:
36 |
37 | Pages
38 | *****
39 |
40 | .. automodule:: philo.models.pages
41 |
42 | .. autoclass:: Page
43 | :members:
44 | :show-inheritance:
45 |
46 | .. autoclass:: Template
47 | :members:
48 | :show-inheritance:
49 |
50 | .. seealso:: :mod:`philo.loaders.database`
51 |
52 | .. autoclass:: Contentlet
53 | :members:
54 |
55 | .. autoclass:: ContentReference
56 | :members:
--------------------------------------------------------------------------------
/docs/releases/0.9.1.rst:
--------------------------------------------------------------------------------
1 | Philo version 0.9.1 release notes
2 | =================================
3 |
4 | The primary focus of the 0.9.1 release has been streamlining and optimization. Requests in 0.9.1 are served two to three times faster than in 0.9. A number of bugs in code, documentation, and migrations have also been corrected.
5 |
6 | New Features and backwards-incompatible changes
7 | +++++++++++++++++++++++++++++++++++++++++++++++
8 |
9 | * :class:`.FeedView` and related syndication code has been migrated to :mod:`philo.contrib.winer` so it can be used independently of :mod:`philo.contrib.penfield`.
10 | * :class:`.FeedView` has been refactored; the result of :meth:`.FeedView.get_object` is now passed into :meth:`.FeedView.get_items` to allow for more flexibility and for :class:`.FeedView`\ s which do not have a :class:`ForeignKey` relationship to the items that the feed is for.
11 | * :class:`.BlogView` has been refactored to take advantage of the more flexible :meth:`~.BlogView.get_object` method. Many of its former entry-fetching methods have been removed.
12 | * :class:`.EmbedWidget` is now used for text fields on, for example, :class:`BlogEntry`. The widget allows javascript-based generation of embed tags for model instances, using the same popup interface as raw id fields.
13 | * :class:`philo.models.Tag` has been removed in favor of an optional requirement for ``django-taggit``. This will allow :mod:`philo` to remain more focused. Migrations are provided for :mod:`philo.contrib.penfield` which losslessly convert :mod:`philo` :class:`~philo.models.Tag`\ s to ``django-taggit`` :class:`Tags`.
14 |
--------------------------------------------------------------------------------
/docs/releases/0.9.2.rst:
--------------------------------------------------------------------------------
1 | Philo version 0.9.2 release notes
2 | =================================
3 |
4 | The primary focus of the 0.9.2 release was repairing the setuptools configuration so that Philo can be installed and updated reliably. In addition, a bug involving the use of :class:`DateTimeField` or :class:`DateField` as the field template for a :class:`JSONAttribute` has been fixed.
--------------------------------------------------------------------------------
/docs/signals.rst:
--------------------------------------------------------------------------------
1 | Signals
2 | =======
3 |
4 | .. automodule:: philo.signals
5 | :members:
6 |
--------------------------------------------------------------------------------
/docs/templatetags.rst:
--------------------------------------------------------------------------------
1 | Template Tags
2 | =============
3 |
4 | .. automodule:: philo.templatetags
5 |
6 | Collections
7 | +++++++++++
8 |
9 | .. automodule:: philo.templatetags.collections
10 |
11 | .. autotemplatetag:: membersof
12 |
13 | Containers
14 | ++++++++++
15 |
16 | .. automodule:: philo.templatetags.containers
17 |
18 |
19 | .. autotemplatetag:: container
20 |
21 |
22 | Embedding
23 | +++++++++
24 |
25 | .. automodule:: philo.templatetags.embed
26 |
27 | .. autotemplatetag:: embed
28 |
29 |
30 | Nodes
31 | +++++
32 |
33 | .. automodule:: philo.templatetags.nodes
34 |
35 | .. autotemplatetag:: node_url
36 |
37 | String inclusion
38 | ++++++++++++++++
39 |
40 | .. automodule:: philo.templatetags.include_string
41 |
42 | .. autotemplatetag:: include_string
43 |
--------------------------------------------------------------------------------
/docs/tutorials/getting-started.rst:
--------------------------------------------------------------------------------
1 | Getting started with philo
2 | ==========================
3 |
4 | .. note:: This guide assumes that you have worked with Django's built-in administrative interface.
5 |
6 | Once you've installed `philo`_ and `mptt`_ to your python path, there are only a few things that you need to do to get :mod:`philo` working.
7 |
8 | 1. Add :mod:`philo` and :mod:`mptt` to :setting:`settings.INSTALLED_APPS`::
9 |
10 | INSTALLED_APPS = (
11 | ...
12 | 'philo',
13 | 'mptt',
14 | ...
15 | )
16 |
17 | 2. Syncdb or run migrations to set up your database.
18 |
19 | 3. Add :class:`philo.middleware.RequestNodeMiddleware` to :setting:`settings.MIDDLEWARE_CLASSES`::
20 |
21 | MIDDLEWARE_CLASSES = (
22 | ...
23 | 'philo.middleware.RequestNodeMiddleware',
24 | ...
25 | )
26 |
27 | 4. Include :mod:`philo.urls` somewhere in your urls.py file. For example::
28 |
29 | from django.conf.urls.defaults import patterns, include, url
30 | urlpatterns = patterns('',
31 | url(r'^', include('philo.urls')),
32 | )
33 |
34 | Philo should be ready to go! (Almost.)
35 |
36 | .. _philo: http://philocms.org/
37 | .. _mptt: http://github.com/django-mptt/django-mptt
38 |
39 | Hello world
40 | +++++++++++
41 |
42 | Now that you've got everything configured, it's time to set up your first page! Easy peasy. Open up the admin and add a new :class:`.Template`. Call it "Hello World Template". The code can be something like this::
43 |
44 |
45 |
46 | Hello world!
47 |
48 |
49 |
Hello world!
50 |
The time is {% now %}.
51 |
52 |
53 |
54 | Next, add a philo :class:`.Page` - let's call it "Hello World Page" and use the template you just made.
55 |
56 | Now make a philo :class:`.Node`. Give it the slug ``hello-world``. Set the ``view_content_type`` to "Page" and the ``view_object_id`` to the id of the page that you just made - probably 1. If you navigate to ``/hello-world``, you will see the results of rendering the page!
57 |
58 | Setting the root node
59 | +++++++++++++++++++++
60 |
61 | So what's at ``/``? If you try to load it, you'll get a 404 error. This is because there's no :class:`.Node` located there - and since :attr:`.Node.slug` is a required field, getting a node there is not as simple as leaving the :attr:`.~Node.slug` blank.
62 |
63 | In :mod:`philo`, the node that is displayed at ``/`` is called the "root node" of the current :class:`Site`. To represent this idea cleanly in the database, :mod:`philo` adds a :class:`ForeignKey` to :class:`.Node` to the :class:`django.contrib.sites.models.Site` model.
64 |
65 | Since there's only one :class:`.Node` in your :class:`Site`, we probably want ``hello-world`` to be the root node. All you have to do is edit the current :class:`Site` and set its root node to ``hello-world``. Now you can see the page rendered at ``/``!
66 |
67 | Editing page contents
68 | +++++++++++++++++++++
69 |
70 | Great! We've got a page that says "Hello World". But what if we want it to say something else? Should we really have to edit the :class:`.Template` to change the content of the :class:`.Page`? And what if we want to share the :class:`.Template` but have different content? Adjust the :class:`.Template` to look like this::
71 |
72 |
73 |
74 | {% container page_title %}
75 |
76 |
77 | {% container page_body as content %}
78 | {% if content %}
79 |
{{ content }}
80 | {% endif %}
81 |
The time is {% now "jS F Y H:i" %}.
82 |
83 |
84 |
85 | Now go edit your :class:`.Page`. Two new fields called "Page title" and "Page body" have shown up! You can put anything you like in here and have it show up in the appropriate places when the page is rendered.
86 |
87 | .. seealso:: :ttag:`philo.templatetags.containers.container`
88 |
89 | Congrats! You've done it!
90 |
--------------------------------------------------------------------------------
/docs/tutorials/intro.rst:
--------------------------------------------------------------------------------
1 | Tutorials
2 | =========
3 |
4 | .. toctree::
5 | :maxdepth: 1
6 |
7 | getting-started
8 | shipherd
9 |
--------------------------------------------------------------------------------
/docs/tutorials/shipherd.rst:
--------------------------------------------------------------------------------
1 | Using Shipherd in the Admin
2 | ===========================
3 |
4 | The navigation mechanism is fairly complex; unfortunately, there's no real way around that - without a lot of equally complex code that you are quite welcome to write and contribute! ;-)
5 |
6 | For this guide, we'll assume that you have the setup described in :doc:`getting-started`. We'll be adding a main :class:`.Navigation` to the root :class:`.Node` and making it display as part of the :class:`.Template`.
7 |
8 | Before getting started, make sure that you've added :mod:`philo.contrib.shipherd` to your :setting:`INSTALLED_APPS`. :mod:`~philo.contrib.shipherd` template tags also require the request context processor, so make sure to set :setting:`TEMPLATE_CONTEXT_PROCESSORS` appropriately::
9 |
10 | TEMPLATE_CONTEXT_PROCESSORS = (
11 | # Defaults
12 | "django.contrib.auth.context_processors.auth",
13 | "django.core.context_processors.debug",
14 | "django.core.context_processors.i18n",
15 | "django.core.context_processors.media",
16 | "django.core.context_processors.static",
17 | "django.contrib.messages.context_processors.messages"
18 | ...
19 | "django.core.context_processors.request"
20 | )
21 |
22 | Creating the Navigation
23 | +++++++++++++++++++++++
24 |
25 | Start off by adding a new :class:`.Navigation` instance with :attr:`~.Navigation.node` set to the good ole' ``root`` node and :attr:`~.Navigation.key` set to ``main``. The default :attr:`~.Navigation.depth` of 3 is fine.
26 |
27 | Now open up that first inline :class:`.NavigationItem`. Make the text ``Hello World`` and set the target :class:`.Node` to, again, ``root``. (Of course, this is a special case. If we had another node that we wanted to point to, we would choose that.)
28 |
29 | Press save and you've created your first navigation.
30 |
31 | Displaying the Navigation
32 | +++++++++++++++++++++++++
33 |
34 | All you need to do now is show the navigation in the template! This is quite easy, using the :ttag:`~philo.contrib.shipherd.templatetags.shipherd.recursenavigation` templatetag. For now we'll keep it simple. Adjust the "Hello World Template" to look like this::
35 |
36 | {% load shipherd %}
37 |
38 | {% container page_title %}
39 |
40 |
41 |
143 |
144 | .. note:: {% recursenavigation %} requires that the current :class:`HttpRequest` be present in the context as ``request``. The simplest way to do this is with the `request context processor`_. Simply make sure that ``django.core.context_processors.request`` is included in your :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting.
145 |
146 | .. _request context processor: https://docs.djangoproject.com/en/dev/ref/templates/api/#django-core-context-processors-request
147 |
148 | """
149 | bits = token.contents.split()
150 | if len(bits) != 3:
151 | raise template.TemplateSyntaxError(_('%s tag requires two arguments: a node and a navigation section name') % bits[0])
152 |
153 | instance_var = parser.compile_filter(bits[1])
154 | key_var = parser.compile_filter(bits[2])
155 |
156 | template_nodes = parser.parse(('endrecursenavigation',))
157 | token = parser.delete_first_token()
158 | return RecurseNavigationNode(template_nodes, instance_var, key_var)
159 |
160 |
161 | @register.filter
162 | def has_navigation(node, key=None):
163 | """Returns ``True`` if the node has a :class:`.Navigation` with the given key and ``False`` otherwise. If ``key`` is ``None``, returns whether the node has any :class:`.Navigation`\ s at all."""
164 | try:
165 | return bool(node.navigation[key])
166 | except:
167 | return False
168 |
169 |
170 | @register.filter
171 | def navigation_host(node, key):
172 | """Returns the :class:`.Node` which hosts the :class:`.Navigation` which ``node`` has inherited for ``key``. Returns ``node`` if any exceptions are encountered."""
173 | try:
174 | return node.navigation[key].node
175 | except:
176 | return node
--------------------------------------------------------------------------------
/philo/contrib/sobol/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | Sobol implements a generic search interface, which can be used to search databases or websites. No assumptions are made about the search method. If SOBOL_USE_CACHE is ``True`` (default), the results will be cached using django's cache framework. Be aware that this may use a large number of cache entries, as a unique entry will be made for each search string for each type of search.
3 |
4 | Settings
5 | --------
6 |
7 | :setting:`SOBOL_USE_CACHE`
8 | Whether sobol will use django's cache framework. Defaults to ``True``; this may cause a lot of entries in the cache.
9 |
10 | :setting:`SOBOL_USE_EVENTLET`
11 | If :mod:`eventlet` is installed and this setting is ``True``, sobol web searches will use :mod:`eventlet.green.urllib2` instead of the built-in :mod:`urllib2` module. Default: ``False``.
12 |
13 | Templates
14 | ---------
15 |
16 | For convenience, :mod:`.sobol` provides a template at ``sobol/search/_list.html`` which can be used with an ``{% include %}`` tag inside a full search page template to list the search results. The ``_list.html`` template also uses a basic jQuery script (``static/sobol/ajax_search.js``) to handle AJAX search result loading if the AJAX API of the current :class:`.SearchView` is enabled. If you want to use ``_list.html``, but want to provide your own version of jQuery or your own AJAX loading script, or if you want to include the basic script somewhere else (like inside the ````) simply do the following::
17 |
18 | {% include "sobol/search/_list.html" with suppress_scripts=1 %}
19 |
20 | """
21 |
22 | from philo.contrib.sobol.search import *
--------------------------------------------------------------------------------
/philo/contrib/sobol/admin.py:
--------------------------------------------------------------------------------
1 | from functools import update_wrapper
2 |
3 | from django.conf import settings
4 | from django.conf.urls.defaults import patterns, url
5 | from django.contrib import admin
6 | from django.core.urlresolvers import reverse
7 | from django.db.models import Count
8 | from django.http import HttpResponseRedirect, Http404
9 | from django.shortcuts import render_to_response
10 | from django.template import RequestContext
11 | from django.utils.translation import ugettext_lazy as _
12 |
13 | from philo.admin import EntityAdmin
14 | from philo.contrib.sobol.models import Search, ResultURL, SearchView
15 |
16 |
17 | class ResultURLInline(admin.TabularInline):
18 | model = ResultURL
19 | readonly_fields = ('url',)
20 | can_delete = False
21 | extra = 0
22 | max_num = 0
23 |
24 |
25 | class SearchAdmin(admin.ModelAdmin):
26 | readonly_fields = ('string',)
27 | inlines = [ResultURLInline]
28 | list_display = ['string', 'unique_urls', 'total_clicks']
29 | search_fields = ['string', 'result_urls__url']
30 | actions = ['results_action']
31 | if 'grappelli' in settings.INSTALLED_APPS:
32 | change_form_template = 'admin/sobol/search/grappelli_change_form.html'
33 |
34 | def unique_urls(self, obj):
35 | return obj.unique_urls
36 | unique_urls.admin_order_field = 'unique_urls'
37 |
38 | def total_clicks(self, obj):
39 | return obj.total_clicks
40 | total_clicks.admin_order_field = 'total_clicks'
41 |
42 | def queryset(self, request):
43 | qs = super(SearchAdmin, self).queryset(request)
44 | return qs.annotate(total_clicks=Count('result_urls__clicks', distinct=True), unique_urls=Count('result_urls', distinct=True))
45 |
46 |
47 | class SearchViewAdmin(EntityAdmin):
48 | raw_id_fields = ('results_page',)
49 | related_lookup_fields = {'fk': raw_id_fields}
50 |
51 |
52 | admin.site.register(Search, SearchAdmin)
53 | admin.site.register(SearchView, SearchViewAdmin)
--------------------------------------------------------------------------------
/philo/contrib/sobol/forms.py:
--------------------------------------------------------------------------------
1 | from django import forms
2 |
3 | from philo.contrib.sobol.utils import SEARCH_ARG_GET_KEY
4 |
5 |
6 | class BaseSearchForm(forms.BaseForm):
7 | base_fields = {
8 | SEARCH_ARG_GET_KEY: forms.CharField()
9 | }
10 |
11 |
12 | class SearchForm(forms.Form, BaseSearchForm):
13 | pass
--------------------------------------------------------------------------------
/philo/contrib/sobol/migrations/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ithinksw/philo/8a772dd4761e3a4b926358d6ebf87c9fc7033ba5/philo/contrib/sobol/migrations/__init__.py
--------------------------------------------------------------------------------
/philo/contrib/sobol/static/sobol/ajax_search.js:
--------------------------------------------------------------------------------
1 | (function($){
2 | var sobol = window.sobol = {};
3 | sobol.favoredResults = []
4 | sobol.favoredResultSearch = null;
5 | sobol.search = function(){
6 | var searches = sobol.searches = $('article.search');
7 | if(sobol.favoredResults.length) sobol.favoredResultSearch = searches.eq(0);
8 | for (var i=sobol.favoredResults.length ? 1 : 0;i" + title + "";
33 | } else {
34 | rendered += "