Element based Renderers #194

Closed
stevenrace opened this Issue May 2, 2012 · 14 comments

Projects

None yet

4 participants

@stevenrace

In short, breaking a document into columns is rather difficult.

I'd prefer to use a grid system - but doing so requires using block DIV between my content within my markdown file. DocPad, of course, treats any markup between these divs as absolute quotes.

Is there a way to modify the markdown converter to follow rules similar to http://maruku.rubyforge.org/div.html? With it, you could use '<div 'markdown=1'> to follow markdown rules within the div.

Additionally, it allows for some neat markdown syntax for DIVs:
http://maruku.rubyforge.org/div.html

Inside first DIV
 +--
  DIV inside DIV
 =--
=--

Or should I be sourcing multiple files or just abusing partials instead?

[awesome project by the way]

Owner
balupton commented May 2, 2012

Hey Steven :)

Thanks for the detailed issue. Perhaps I'm not with it, but would you be able to elaborate on what you mean by "document into columns" and "grid system", and provide some example links to what your desired outcome looks like (from a design point of view, rather than a technical point of view). That will really help with my understanding of the limitation, and how to best come up with the right solution to it :)

As always, thanks mate.

Admittedly, using a 'grid system' (such as Twitter Bootstrap 2 or 960Grid is the ultimate goal. I think the issue with DIVs can be explained like so:

Say I have a document 'foo.md' which contains:

## Blue
 It's the best color
## Red
Is obnoxious 

Now I can render my document with a Stylesheet to change the styling of H2s and so on. But what if I wanted 'Blue is the best color' to have a blue background - and Red have a red background.

I would then need to do something like:

<div class="blue">

## Blue
 It's the best color

</div>
<div class="red">
## Red
Is obnoxious 

</div>

However doing so then breaks the H2 markup and it renders as ## Blue.

Other markdown engines allow for something like:

<div class="blue" markdown=1>

## Blue 
is the best color

</div>

Which renders markdown within DIVs that contain ``markdown=1`. Also note the extra line space between the content and the DIVs.

The grid systems mention above use DIV/SPAN elements to position content....

I hope this make sense.

Owner
balupton commented May 2, 2012

Sweet, that certainly cleared things up :) Thanks for that!

It is a very interesting problem, while it would be pretty easy to create a new markdown plugin that follows those rules I'm not it would be the most scalable solution - I imagine that this type of problem affects all pre-processors and is not just markdown.

Perhaps if we amend the existing plugins to utilise element types, doing so would provide the following solution based on your code examples:

<div class="blue"><markdown>
## Blue
 It's the best color
</markdown></div>
<div class="red"><markdown>
## Red
Is obnoxious
</markdown></div>

Which would be rather easy to do, and certainly be awesomely scalable. Especially with the planned features coming up in later versions of DocPad. E.g. when combined with the planned GetText Plugin, it would allow us to utilise pre-processors inside our configuration files.

What are your thoughts? Does this solution feel right to you too? Would it fit your use case?

That would be perfect.

I'll set aside some free time this weekend to start learning about plugins.

Owner

Okay, just got to working on this today. Looks like we may have to make this a bit less appealing than before.

Instead of say:

<markdown>
  # This is some markdown
</markdown>

It would be more something like:

<docpad:render:markdown>
  # This is some markdown
</docpad:render:markdown>

<docpad:render:html.md.eco>
  # This is some <%- 'eco'.toUpperCase() %> with some markdown
</docpad:render:html.md.eco>

Obviously, that is quite verbose and ugly, but it allows us to use the same API for plugins... Will think about this more.

Owner

Other options are:

using 2 instead of .
<render:md2html>

with property
<render extensions="html.md">blah</render>

as part of the text plugin:
<text render="markdown"># Markdown</text>
<text render="html.md"># Markdown</text>
<t render="html.md"># Markdown</t>

updates to traditional text plugin:
<text property="site.title"/>
<text var="site.title"/>
<text>site.title</text>
<t>site.title</t>

mix and matching for text plugin:
<text render="html.md" property="site.title"/>
Owner

ok, this would be good:

---
title: Text Plugin Example
markdownSource: Founder of [Bevry](http://bevry.me "Visit Website")
---

This document is titled: <text>document.title</text>
This document is titled: <t>document.title</t>
My creator's firstname is: <t>creator.firstname</t>
My creator's lastname is: <t>creator.lastname</t>
My creator's fullname is: <t>creator.fullname</t>
My filename is: <t>document.filename</t>

Here is a markdown example: <render type="markdown">Here we do some rendering with **markdown**</render>
Here is a markdown example: <r type="markdown">Here we do some rendering with **markdown**</r>
Here is a markdown and eco example: <r type="html.md.eco">Here we do some rendering with **markdown** and <%- 'eco'.toUpperCase() %></r>

Here is a markdown property example: <r type="markdown"><t>document.markdownSource</t></r>

or:

---
title: Text Plugin Example
markdownSource: Founder of [Bevry](http://bevry.me "Visit Website")
---

This document is titled: <t>document.title</t>
My creator's firstname is: <t>creator.firstname</t>
My creator's lastname is: <t>creator.lastname</t>
My creator's fullname is: <t>creator.fullname</t>
My filename is: <t>document.filename</t>

Here is a markdown text example: <t type="markdown">Here we do some rendering with **markdown**</t>
Here is a markdown and eco text example: <t type="html.md.eco">Here we do some rendering with **markdown** and <%- 'eco'.toUpperCase() %></t>

Here is a markdown property example: <t type="markdown">document.markdownSource</t>

However, we will start to handle some more advanced use cases here.... And this means that we will need to implement something like jsdom or cheerio to do the dom parsing of the documents. Both of which seems incredibly unreliable at the current state. So I think this will have to be put on the backburner for now. If you need to abstract stuff, the partials plugin will have to do. Sorry :(

Owner

BOOOYEAH!!!! DID IT!!!! WOOT WOOT!

Here is what we can now do:

--- coffee
title: """
    this is our **document!**
    """
titleEmbed: """
    our title is <text>document.title</text>
    """
ecoExample: """
    <text render="eco">
    This is <%- 'eco'.toUpperCase() %>
    </text>
    """
markdownExample: """
    <text render="markdown">
    This is **amazing!**
    </text>
    """
ecoInMarkdownExample: """
    <t render="markdown">
    This is **amazing!**
    <text>document.ecoExample</text>
    isn't it?
    </t>
    """
ecoThenMarkdownExample: """
    <text render="html.md.eco">
    This is **amazing!**
    This is <%- 'eco'.toUpperCase() %>
    isn't it?
    </text>
    """
---

TITLE:
<t>document.title</t>

<text>document.title</text>

<text>document.titleEmbed</text>


TITLE MARKDOWN:

<text render="markdown">document.title</text>

<text render="markdown">document.titleEmbed</text>


MARKDOWN:

<text>document.markdownExample</text>

<text render="markdown">
This is **amazing!**
</text>


ECO:

<text>document.ecoExample</text>

<text render="eco">
This is <%- 'eco'.toUpperCase() %>
</text>


ECO IN MARKDOWN:

<text>document.ecoInMarkdownExample</text>

<t render="markdown">
This is **amazing!**
<text>document.ecoExample</text>
isn't it?
</t>

<t render="markdown">
This is **amazing!**
<text render="eco">
This is <%- 'eco'.toUpperCase() %>
</text>
isn't it?
</t>

<text:one render="markdown">
This is **amazing!**
<text:2 render="eco">
This is <%- 'eco'.toUpperCase() %>
</text:2>
isn't it?
</text:one>


ECO THEN MARKDOWN:


<text>document.ecoThenMarkdownExample</text>

<text render="html.md.eco">
This is **amazing!**
This is <%- 'eco'.toUpperCase() %>
isn't it?
</text>

will be in the next release :)

Well done! I'm loving Docpad in the short time I've been using it but waiting on this feature to launch a site! No pressure or anything!

I found a way around this by using the partials plugin, I put the divs in partial files and call them up in the markdown files.

My partial.html looks like this:

</div><div class = "left">

and the whatever.html.md.eco that I often edit looks like:

<%-@partial('left.html.md') %>

[left side](http://google.com)

[left side](http://google.com)


<%-@partial('right.html.md') %>

[right side](http://google.com)

[right side](http://google.com)

This only works if the html isn't changed very often because you need to do a "docpad generate" every time you want the partials to update because it just throws an "An error occured: Cannot read property 'length' of undefined TypeError: Cannot read property 'length' of undefined" when saved. That might be a bug, I'm not sure. Luckily markdown handles spans which gives you some flexibility.

Owner
balupton commented Jul 4, 2012

Sweet. That is a nifty way of doing it, and thanks for letting me know. The use of partials for such use cases has also influenced the architecture of this solution (in a positive way) :)

I've pushed the changes to the dev branch and it is now stable. Will do a publish soon enough :)

@balupton balupton closed this Jul 7, 2012
lzrski commented Dec 14, 2012

Hello!

How can I use it inside coffeekup layout? I want to display string from document meta and render it using markdown.

My document (say /src/documents/index.html.md) is like:

---
layout: default
someMeta: This is **markdown** formated meta data.
---

Some content

In coffeekup layout (say /src/layouts/default.html.coffee) I tried this, with no success:

[...]
section {class: "meta}, ->
  text {render: "md"}, @document.meta.someMeta
[...]

How to make it work? Thanks in advance.

Owner

Yeah as t and text are special elements that the text plugin defines, they are not included in coffeecup by default. However coffeecup gives us the tag helper which will accomplish what we want:

[...]
section {class: "meta}, ->
  tag 'text', {render: "md"}, @document.meta.someMeta
[...]

Discovered this via https://github.com/gradus/coffeecup/blob/master/docs/reference.md#tag

Update: added as a note to the text plugin readme

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment