/ ember.js

Markdown in an ember.js app

last updated Sept 22/16

I'm trying to build a web app for creating and organizing "cue cards" for research articles. You can find the github repo of my project here: Acardema

(stupid name is temporary)

This is still all early-stages, mostly I'm learning about ember.js and databases and how to work with them. One thing I know pretty early on for my app is that I want to have some kind of text formatting within text areas. For instance, if I'm writing notes in the intro section:

  • I should be able to add bullet points
    • Easily.

Markdown

I decided to look at Markdown, as I'm familiar with it through Ghost and Github and it seems like the right direction to go.

One solution I found right away was ember-refined-remarkable by very-geek. It's very simple to use. You can install it through ember, so it doesn't take much more than a

ember install ember-refined-remarkable

to get it running.

Usage is easy. If you want to insert a block of markdown text, you'd just add something like this:

{{#mark-down}}
{{!-- markdown text --}}
{{/mark-down}}

It's basically an ember port of jonschlinkert's remarkable markdown parser, so usage is mostly the same.

Now one unfortunate problem I encountered is that I couldn't figure out how to update the text dynamically. I think it must be possible, the remarkable demo has something like it happening. I probably just need to study it more, but I wasn't sure where to point to for updating text without breaking it.

edit: I'm an idiot. Usage is really simple.

Dynamically changing Markdown text

The idea with the app is that I have permanent text areas for different sections of the card (abstract, methods, etc). These areas are updated every time you choose a card; when you open a card, that cards database values are pulled and placed into where they need to go. The text is stored as was typed originally in the database.

In my template file (called cardview.hbs) I've got a number of different div sections for each variable (abstract, intro, methods, etc). For instance, here's what the space for the Abstract looks like:

<div class="abstractspace cardslot">
    <h5 class="slotItem slotLabel">Abstract: </h5>
    <div class="cardAbstract slotItem slotDisplay"></div>
    {{textarea value=abstract class="slotCreate slotItem createBox"}}
</div>

I've got an overarching container abstractspace, an H5 label, an empty div class cardAbstract, and a text area. The text area is the input box that appears when you try to create a card, and the empty div is what will actually be shown.

So now say you select a card that you want to view. The javascript for this page is kept under controllers/cardview.js. When you click on a cards entry, it's set to call a function viewCard(card).

The goal is for this function to go grab the abstract from the database for this specific card and put that text into the empty div using Markup. It turns out this is really simple! You only need these four lines:

var md = new Remarkable(); //load markdown variable
var abstract = card.get('abstract'); //get abstract from database
var abstractMarkdown = md.render(abstract); //convert text to Markdown
Ember.$('.cardAbstract').html(abstractMarkdown); //place converted text into page.

note this was separated for clarity, but really you can compress this into two lines.

The key I was missing before is md.render(). Any text within this function will be converted into Markdown. So for instance:

md.render("## Hello there!");

will render as:

<h2>Hello there!</h2>

Through this it's really easy to load Markdown onto the page dynamically (using Ember's jQuery helper to point at classes). This basically solves all the problems I was having, and will be the solution I'll be using going forward.


My previous hack solution

My hack solution right before was using gcollazo's ember-cli-showdown. This is a real-time markdown render component that looks at the value of an assigned text area. I'm not sure if it looks anywhere else, documentation isn't great for this.

Basically all I did was add in extra hidden text areas in each section for showdown to read from. I set the value of these text areas dynamically through javascript as you select different options.

This solution wasn't great. Major problem was that those text areas didn't refresh as you navigate to a different page, something I didn't expect. There might be a way to fix this, but I felt like it was going to lead me down a rabbit hole of problem solving when the real solution was to figure out ember-refined-remarkable.

Kyle

Kyle

I do tactile research—It's a touchy subject. Psych/Neuro grad student and creator of LittleGadget, a channel about Science and Videogames.

Read More