{ "info": { "author": "Colin T.A. Gray", "author_email": "colinta@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: End Users/Desktop", "Intended Audience :: System Administrators", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Internet", "Topic :: Internet :: WWW/HTTP :: Site Management", "Topic :: Software Development", "Topic :: Software Development :: Build Tools", "Topic :: Software Development :: Code Generators", "Topic :: Text Processing" ], "description": "======================\nThe Strange Case of...\n======================\n\nIt's yet another static site generator. Have you seen `jekyll`_?\n`hyde`_? Yup. Like those.\n\nBut this one is:\n\n1. Written in python, unlike ``jekyll``\n2. **NOT** complicated, unlike ``hyde``. And I mean *really* **NOT** complicated.\n\nI just read about `nanoc`_, and realized that it is the Ruby equivalent to\nStrangeCase. I commend them! I had considered porting StrangeCase to Ruby\n(and maybe I will some day, just for kicks), but for now, I would say to\nRubyists: use `nanoc`_.\n\n\n------------\nINSTALLATION\n------------\n\n::\n\n $ pip install StrangeCase\n $ scase # generates the site\n $ scase --watch # generates the site and watches\n # for changes to source files\n\n\n-----\nHELP!\n-----\n\nAlready!? Geez::\n\n #strangecase @ irc.freenode.net\n\n (i'm colinta)\n\n\n-----------\nQUICK START\n-----------\n\n1. In your project folder, make a ``site/`` and ``public/`` folder.\n2. Put ``index.j2`` in ``site/``, and put some html in there.\n3. Add YAML front matter to that file. It looks like this::\n\n ---\n title: My first StrangeCase site\n ---\n \n ...\n\n4. Use that YAML in your page using `Jinja2`_'s template language syntax::\n\n ---\n title: My first StrangeCase site\n ---\n \n
Project number #{{ order }} started on {{ created_at | date }}
\n {% endblock %}\n\nA little shorter than our original ``index.j2``. Notice I've left out the YAML\nfront matter, and yet I am using the variables `title`, `order`, and\n`created_at`. Where do they get their value from?\n\nThe file name, and configurators.\n\n::\n\n 001_2012_02_27_first_project\n \\+/ \\---+----/ \\-----+-----/\n | | |\n | | +-title\n | |\n | +-created_at\n |\n +-order\n\nIn this way, you get some variables for free just by naming your files with a\ndate and/or order prefix. We are looking at the by-product of \u201cconfigurators\u201d.\nThey are passed the source file name and the config dictionary. There are some\nthat *have* to run, and some that are optional but enabled by default.\n\nAnyway, if you tried to run StrangeCase right now, you would get the following\nerror::\n\n $ scase\n ...\n jinja2.exceptions.TemplateAssertionError: no filter named 'date'\n\nNo worries, there is a `date` filter built into StrangeCase. It's just not\nenabled. So add a config.yaml file to the project root::\n\n project\n \u251c\u2500\u2500 config.yaml\n \u251c\u2500\u2500 layouts\n \u2502\u00a0\u00a0 \u2514\u2500\u2500 base.j2\n \u251c\u2500\u2500 public\n \u2502\u00a0\u00a0 \u2514\u2500\u2500 ...\n \u2514\u2500\u2500 site\n \u251c\u2500\u2500 index.j2\n \u2514\u2500\u2500 projects\n \u251c\u2500\u2500 001_2012_02_27_first_project.j2\n \u251c\u2500\u2500 002_2012_02_28_second_project.j2\n \u2514\u2500\u2500 003_2012_02_27_third_project.j2\n\nand add the date filter::\n\n filters:\n date: strange_case.extensions.date.date\n\n*Now* you can run StrangeCase with no errors, which will generate::\n\n \n \nProject number #1 started on 27 Feb 2012
\n\n \n\nMoving along. Now let's create a project listing at ``projects/index.j2``. We\nneed a way to \"fetch\" the project pages. This is going to be very easy,\nbecause really all that StrangeCase *does* is build a resource tree. And we\ncan walk that tree using the node names. So if we just iterate over the\n``projects/`` folder, we'll have our project nodes.\n\nAdd ``index.j2`` to ``site/projects/`` ::\n\n project\n \u251c\u2500\u2500 config.yaml\n \u251c\u2500\u2500 layouts\n \u2502\u00a0\u00a0 \u2514\u2500\u2500 base.j2\n \u251c\u2500\u2500 public\n \u2502\u00a0\u00a0 \u2514\u2500\u2500 ...\n \u2514\u2500\u2500 site\n \u251c\u2500\u2500 index.j2\n \u2514\u2500\u2500 projects\n \u251c\u2500\u2500 index.j2 # <===\n \u251c\u2500\u2500 001_2012_02_27_first_project.j2\n \u251c\u2500\u2500 002_2012_02_28_second_project.j2\n \u2514\u2500\u2500 003_2012_02_27_third_project.j2\n\n``index.j2``::\n\n {% extends \"layouts/base.j2\" %}\n\n {% block content %}\n {% for project in site.projects %}\n \n {% endfor %}\n {% endblock %}\n\nIterating over folders is a very easy thing to do in StrangeCase. It's how you\ndo things like create an index page, as we saw here, or create a photo blog\n(``for photo in site.images.my_fun_trip``). It is the thing that I wanted to be\n*really* easy, because I couldn't figure out, at a glance, how to do it in\njekyll or hyde (it is possible in hyde, I think).\n\nNotice that when we iterate over the ``site.projects`` folder, it doesn't\ninclude the ``index.html`` file. Makes sense, though, right? The index page\nis considered to be the same \"page\" as the folder. Even though they are\nseperate nodes, they have the same URL.\n\nTo wrap things up, let's make a link to the project page from the home page.\nEvery node has a ``url`` property, and you can access pages by their name.\n\"name\" is whatever is \"leftover\" after the created_at date, order and extension\nhave been pulled out. I'll add a link to the second project to demonstrate\nthis::\n\n ---\n title: My first StrangeCase site\n ---\n {% extends \"layouts/base.j2\" %}\n {% block content %}\nMy favorite project: My second project
\n {% endblock %}\n\n\nThis wraps up the tutorial! Now, I'll explain the inner workings.\n\n---------------\nTIPS AND TRICKS\n---------------\n\nHere are some quick little neat things.\n\n1. You'll need a good, solid config.yaml. Just copy and paste this when you\n start a new site::\n\n extensions:\n - strange_case.extensions.misaka.MarkdownExtension\n filters:\n date: strange_case.extensions.date.date\n markdown: strange_case.extensions.misaka.markdown\n json: json.dumps\n sha: strange_case.extensions.hashlib.sha\n processors:\n - strange_case.extensions.image\n - strange_case.extensions.category\n - strange_case.extensions.paginated\n - strange_case.extensions.scss\n\n2. Iterate over a folder of pages, or a folder of assets, using\n ``{% for page in site.folder.subfolder %}``. There is no \"easy\" way to\n iterate over a folder that contains folders - what you really want there is\n to get the index file of the folder, it will contain the meta data (title,\n created_at, etc) that you probably want to display in the listing. I will\n try and fix this, but probably won't until someone asks for it.\n\n3. Do not mix pages and assets. You *can* do it, but things get goofy when you\n try and iterate over the folder. If you ``{% for page in site.folder %}``,\n you will end up with *both* types of file. If you *really* want to mix them,\n you can iterate over just the pages (and exclude index.html files) using\n ``iter_pages``, introduced in v4.3.0.\n\n4. You can assign \"pointers\" in your YAML front matter. They look like this::\n\n page ->: site.other.page\n\n If your asset folders are getting unwieldy\n (``site.static.images.posts.pics_of.kittens``), use this trick to shorten it\n down in your template. In this case you *must* prefix the pointer with\n ``my.``, because jinja will not know how to lookup \"page ->\" when you say\n only \"page\", and I have not devised a workaround yet::\n\n ---\n pics ->: site.static.images.posts.pics_of.kittens\n ---\n {% for pic in my.pics %}\n{{ loop.index }}. {{ blog.title }}
\n {% endfor %}\n\n=> ::\n\n1. Blog Title
\n2. Blog Title
\n\n**Note:** Files named ``index.html`` will not be included in this list. This is\na very reasonable design decision, but I can imagine a situation where you have\na file (think ``robots.txt``) that *also* doesn't belong in the iterable pages\nlist. So ``iterable: false`` is available as a config setting.\n\nIterate over a folder of images\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n {% for image in site.static.image %}\nThe date is {{ 'now'|date }}.
\nThe date is 06 May 2012.
\n\nstrange_case.extensions.inflect.pluralize\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nPluralizes a variable::\n\nCategory - {{ title|pluralize }}\n\n::\n\n filters:\n pluralize: strange_case.extensions.inflect.pluralize\n\nstrange_case.extensions.uuid.uuid\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThis filter generates a UUID based on the provided input. The UUID is\ngenerated by taking a SHA1 hash of the input combined with a namespace\nidentifier. The available namespaces are:\n\n* ``dns`` for fully-qualified domain names as input\n* ``url`` for URLs (default)\n* ``oid`` for ISO OID input\n* ``X500`` for X.500 DNs in either DER or text format\n\n::\n\n