{ "info": { "author": "James Arthur", "author_email": "firstname.lastname@largeblue.com", "bugtrack_url": null, "classifiers": [ "Environment :: Web Environment", "Framework :: Zope3", "Intended Audience :: Developers", "License :: Public Domain", "Natural Language :: English", "Programming Language :: Python", "Topic :: Internet :: WWW/HTTP :: WSGI :: Application" ], "description": "largeblue.pages aims to solve a fairly common, relatively simple web development\nrequirement:\n\n* all or some of a website's pages need to be editable via a WYSIWYG editor\n (e.g.: by a client or non-technical website administrator)\n* however, the site's developer(s) most definitely do not want to edit the \n pages' content via a WYSIWYG editor, they (you) want to use their (your) \n normal text editor and possibly version control, etc.\n* some pages of the website may not be appropriate to be editable via a WYSIWYG \n (e.g.: where javascript is being used on a specific markup structure for a\n bespoke page)\n* the website structure should ideally be flexible, so new pages and sections \n can be added recursively without re-development\n\nlargeblue.pages:\n\n* provides Page Container and Page content objects, where pages can contain any\n number of sub pages and so on ad infinitum\n* a Page's content property is setup to be edited by a WYSIWYG editor (in fact, \n we configure and patch the default z3c.widget.tiny WYSIWYG widget to make sure \n it stores valid xhtml and that the output source code nesting has each element \n indented by 2 spaces)\n* each Page and it's html content can also be accessed by webdav (largeblue.pages \n uses bebop.webdav's patching of zope.app.dav / z3c.dav to provide read and write \n webdav access) so that a page appears as a folder, containing a main_content.html \n and any number of other page folders. This way, the whole structure of pages \n can be edited without going near a web browser.\n\nThere are some other useful features:\n\n* @@edit.html and @@ordering.html are custom ZMI views hung off a page that can \n be added to an admin skin, where the @@ordering.html (called 'Manage Contents')\n provides a custom, orderable container view based on largeblue.order, so pages\n can be moved up and down as well as renamed, cut pasted, deleted and added, etc.\n* every Page Container has a property called 'index' that, at any time, contains a \n snapshot of the current pages structure (it's updated whenever a Page created, \n modified or deleted event happens) - note, you can have multiple page containers \n are they all maintain their own index\n* the obj.__name__ of each page is forced to be a sane 'no cross browser href\n issues' snippet of text\n* pages have a flag attribute, intended to be referenced in a view class (see \n ./browser/index.py) to control whether they are 'simple' pages which just render \n the managable content or bespoke pages that need to be special cased\n\nTo use largeblue.pages, you'll just need to add the package to your site.zcml (or\nequivalent) (include the largeblue.pages package and include the overrides.zcml\nas overrides).\n\nAnyway, let's see it in action.\n \n >>> import transaction, pprint\n >>> from zope.component import createObject\n >>> from zope.event import notify\n >>> from zope.lifecycleevent import ObjectCreatedEvent\n >>> from zope.lifecycleevent import ObjectModifiedEvent\n >>> from bebop.ordering.interfaces import IOrdering, IOrderable\n >>> from largeblue.pages.interfaces import IPage, IPageContainer, IFile\n >>> from largeblue.pages.page import PageContainer\n\nCreate a page container.\n \n >>> app['pages'] = PageContainer()\n\nCreate a page.\n\n >>> page1 = createObject('largeblue.pages.Page')\n >>> page1.__name__ = 'page1'\n >>> page1.title = u'Page 1'\n >>> for item in page1:\n ... print item\n ...\n >>> page1.content\n u''\n >>> page1.flag\n u'Static'\n \nAdd it to the container and fire a created event.\n\n >>> app['pages']['page1'] = page1\n >>> notify(ObjectCreatedEvent(page1))\n \nAnd we see it now contains a file called html_content.html and that this is\neditable via the Page's content property.\n \n >>> page1 = app['pages']['page1']\n >>> for item in page1:\n ... print item\n ...\n main_content.html\n >>> page1['main_content.html'].contentType\n 'text/html'\n >>> page1.content\n '
Under construction
'\n >>> page1['main_content.html'].data\n '
Under construction
'\n >>> page1['main_content.html'].data = '
Foo bar
'\n >>> page1['main_content.html'].data\n '
Foo bar
'\n >>> page1.content\n '
Foo bar
'\n >>> page1.content = '
Under construction
'\n >>> page1.content\n '
Under construction
'\n >>> page1['main_content.html'].data\n '
Under construction
'\n\nLet's look at the Page Container's index property:\n\n >>> pages = app['pages']\n >>> for item in pages:\n ... print item\n ...\n page1\n >>> pages.index\n [{'title': u'Page 1', 'pages': [], 'label': u'page1'}]\n >>> page2 = createObject('largeblue.pages.Page')\n >>> page2.__name__ = 'movies'\n >>> page2.title = u'Movies'\n >>> pages['movies'] = page2\n >>> for item in pages:\n ... print item\n ...\n movies\n page1\n >>> notify(ObjectCreatedEvent(page2))\n >>> pages.index\n [{'title': u'Page 1', 'pages': [], 'label': u'page1'}, {'title': u'Movies', 'pages': [], 'label': u'movies'}]\n\nWe can nest Pages within Pages:\n\n >>> page3 = createObject('largeblue.pages.Page')\n >>> page3.__name__ = 'horror'\n >>> page3.title = u'Scary Horror Films'\n >>> notify(ObjectCreatedEvent(page3))\n >>> pages['movies']['horror'] = page3\n >>> page4 = createObject('largeblue.pages.Page')\n >>> page4.__name__ = 'texas'\n >>> page4.title = u'The Texas Chainsaw Massacre'\n >>> notify(ObjectCreatedEvent(page4))\n >>> pages['movies']['horror']['texas'] = page4\n\nCheck the index again:\n\n >>> pprint.pprint(pages.index)\n [{'title': u'Page 1', 'pages': [], 'label': u'page1'},\n {'label': u'movies',\n 'pages': [{'label': u'horror',\n 'pages': [{'label': u'texas',\n 'pages': [],\n 'title': u'The Texas Chainsaw Massacre'}],\n 'title': u'Scary Horror Films'}],\n 'title': u'Movies'}]\n\nThe idea is that the index can be referenced by a dynamic navigation, say, without\nhaving to traverse the Pages' heirarchy every time. Key to this is the ability to\norder the pages, so you can control the order in which the navigation items are \ndisplayed.\n\nWe've patched bebop.ordering to achieve just this. Let's look at the root \ncontainer's order:\n\n >>> IOrdering(pages).getNames()\n [u'page1', u'movies']\n >>> IOrdering(pages).keys()\n [0, 1]\n >>> IOrdering(pages).upOne([1])\n >>> IOrdering(pages).getNames()\n [u'movies', u'page1']\n >>> notify(ObjectModifiedEvent(pages))\n >>> pprint.pprint(pages.index)\n [{'label': u'movies',\n 'pages': [{'label': u'horror',\n 'pages': [{'label': u'texas',\n 'pages': [],\n 'title': u'The Texas Chainsaw Massacre'}],\n 'title': u'Scary Horror Films'}],\n 'title': u'Movies'},\n {'title': u'Page 1', 'pages': [], 'label': u'page1'}]\n \nThere's more in the largeblue.order.README.txt on this, basically what we've done\nis limited the orderable contents of an Ordering container to only include pages:\n\n >>> for item in page3:\n ... print item\n ...\n main_content.html\n texas\n >>> IOrdering(page3).getNames()\n [u'texas']\n\nPlus we've extended the functionality of the ordering container view to accomodate\nthe 'normal' actions too. This way, an admin skin ZMI layer need only expose the\n@@edit.html and @@ordering.html views on the Page, thus hiding anything other than\nPages in the Page container view (e.g.: main_content.html, .svn files, etc.).\n\nTo connect via webdav to the Pages structure, simply connect to your site instance, \neg: http://localhost:8080 and, voila, you'll see a structure like:\n\n- pages\n \n - page1\n \n - main_content.html\n \n - movies\n \n - main_content.html\n - texas\n \n - main_content.html\n\nEdit the main_content.html files to edit the main content for the pages. Be careful\nthough - don't rename it and don't save invalid xhtml. The point being that only a\ncompetant developer who knows this should be given webdav access.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://pesto.largeblue.net/trac/browser/largeblue/devel/largeblue.pages", "keywords": "zope largeblue pages cms wysiwyg webdav orderable", "license": "Public Domain (note, vendor code contained within has own licenses)", "maintainer": null, "maintainer_email": null, "name": "largeblue.pages", "package_url": "https://pypi.org/project/largeblue.pages/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/largeblue.pages/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://pesto.largeblue.net/trac/browser/largeblue/devel/largeblue.pages" }, "release_url": "https://pypi.org/project/largeblue.pages/0.3.1/", "requires_dist": null, "requires_python": null, "summary": "A simple approach to making a zope website's pages content managable", "version": "0.3.1" }, "last_serial": 794055, "releases": { "0.2": [ { "comment_text": "", "digests": { "md5": "2d883b8426c839ade55e4d557c2644dd", "sha256": "f124e04a8dce9db4de3e7394814be1daec81f2ef9196d0224df7bf7de4e12547" }, "downloads": -1, "filename": "largeblue.pages-0.2.tar.gz", "has_sig": false, "md5_digest": "2d883b8426c839ade55e4d557c2644dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 197334, "upload_time": "2008-09-03T13:27:23", "url": "https://files.pythonhosted.org/packages/b7/2a/5fb374d1267a4251e9bce5928b975fd63c9779030693a51ba15c9ced8007/largeblue.pages-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "27447bc1c224635f14e23042a27c61c9", "sha256": "1b55c0d4aca86fcff40f7951f9e5d28b42fe1e729b64acd9e9202e9ca9cfb1a8" }, "downloads": -1, "filename": "largeblue.pages-0.3.tar.gz", "has_sig": false, "md5_digest": "27447bc1c224635f14e23042a27c61c9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27827, "upload_time": "2008-09-06T16:35:10", "url": "https://files.pythonhosted.org/packages/3e/e3/1ea39f172edc976154ed9674239897b59e16bc38287975f5b9e01886ce59/largeblue.pages-0.3.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "dddea8f710e59d88561dc17efc82b751", "sha256": "09bb64c72c215d5550f31fa71cf72a914646f1acea550c772e899fb78bc4d934" }, "downloads": -1, "filename": "largeblue.pages-0.3.1.tar.gz", "has_sig": false, "md5_digest": "dddea8f710e59d88561dc17efc82b751", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27262, "upload_time": "2008-09-12T15:16:04", "url": "https://files.pythonhosted.org/packages/f0/a2/e5302a5a85caa8c7e6d68a37e5ad85860b9e22bb42dfea6eea65ae8970f8/largeblue.pages-0.3.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "dddea8f710e59d88561dc17efc82b751", "sha256": "09bb64c72c215d5550f31fa71cf72a914646f1acea550c772e899fb78bc4d934" }, "downloads": -1, "filename": "largeblue.pages-0.3.1.tar.gz", "has_sig": false, "md5_digest": "dddea8f710e59d88561dc17efc82b751", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27262, "upload_time": "2008-09-12T15:16:04", "url": "https://files.pythonhosted.org/packages/f0/a2/e5302a5a85caa8c7e6d68a37e5ad85860b9e22bb42dfea6eea65ae8970f8/largeblue.pages-0.3.1.tar.gz" } ] }