Mountainwerks.org

on

Ember

What is it?

  • 22 year diary
  • Tracks apprenticeship
  • To make friends
  • Play with ideas

Title Text

Community

In 2010

2015, node wintersmith

My Values

  • Non-commercial
  • Archivable / simple
  • Honesty
    • Fear
    • Mistakes

Goals

I wanted the site to look good on mobile

 

To learn about EmberJS!

 

To have a better mapping & JavaScript playground in general.

Details

  • Node 6.12.2
  • Ember-cli 2.5.0
  • grunt-cli v1.2.0
    • (for deployment, for now)
  • Wercker deployment (TBD)
    • Docker container
    • rsync-deploy to mountainwerks.org

Design choices

  • Static site - no database
  • Markdown for content
  • Support existing workflows
    • Lightroom / Flickr
      • (though this has to change)
    • Google Earth

Cost a few bucks, but worth it

Structure

  • /
    • /articles
      • /trips
        • /1997
        • ...
        • /2018
          • hohekiste.md
      • /philosophy
        • robots-one.md
    • /app
      • ...
    • /public
      • /articles
        • ...images under here

A trip is a route

// file: app/routes/sections/trip.js
import Ember from 'ember';

export default Ember.Route.extend({
    model: function (params) {
        return Ember.$.getJSON("/articles/trips/" + 
            params.slug + ".json").then(function (results) {
            console.log(results.description);
            return results;
        });
     }
});

List of trips

// file: app/routes/sections/trips.js
import Ember from 'ember';

export default Ember.Route.extend({
  model: function () {
    return Ember.RSVP.hash({
      trips: Ember.$.getJSON("/articles/trips/index.json")
          .then(function (results) {
        return results;
      }),
      locations: Ember.$.getJSON("/articles/trips/locations.json")
          .then(function (results) {
        return results;
      })
    });
  },

  setupController(controller, model) {
    this._super(...arguments);
    Ember.set(controller, 'trips', model.trips);
    Ember.set(controller, 'locations', model.locations);
  }
});

Broccoli pre-build

  • Convert markdown to json
  • Create indexes for articles
  • Transform KML into json for locations

In ember-cli-build.js

Report Markdown

---
title: The Vajolet Towers and Punta Emma
date: 2011-6-27
layout: post
location: Vajolet Towers
---
Also posted on Summitpost.org 
[here](http://www.summitpost.org/vajolet-and-punta-emma/725512)

[![](http://farm4.static.flickr.com/3070/5872745355_d532767ce4.jpg)](http://www.flickr.com/photos/ripsawridge/5872745355/)

A fellow American, Pete, and I visited the Rosengarten area of the Dolomites
for a quick introduction to that beautiful group of spires. We had hoped
to get three full days of climbing in, but bad weather effectively canceled
the first day, and then the logistics of travel times and appointments
caused us to shorten the last day considerably. But still, a day and a
half of movement over good stone is nothing to sneeze at! We had a great
time and planned many future ascents.

...

Rendering report list

<div class="report-list">
  <table class="table table-stripped table-bordered">
    <thead>
      <tr> <td>Date</td> <td>Where</td> <td>Notes</td> </tr>
    </thead>
    <tbody>
      {{#each trips as |trip|}}
          <tr>
            <td>{{date-mmyyyy trip.date}}</td>
            <td>{{#link-to 'sections.trip' trip.slug}}
                  {{trip.title}}
                {{/link-to}}
            </td>
            <td>{{trip.blurb}}</td>
          </tr>
      {{/each}}
    </tbody>
  </table>
</div>

File app/templates/sections/trips.hbs

Broccoli pre-build

function transformGeoLocations(input_kml, output_json, trip_index) {                                                         
  var kml = fs.readFileSync(input_kml);                                                                                      
  var json = xml2json.toJson(kml, { object: true });                                                                         
  var maps = json.kml.Document.Folder.Folder; // the locations folder.                                                       
  // There should be several map folders.                                                                                    
  let data = [];                                                                                                             
  maps.forEach((map) => {                                                                                                      
    map.Placemark.forEach((placemark) => {                                                                                       
      let obj = {                                                                                                                  
        name: placemark.name,
        location: [parseFloat(placemark.LookAt.latitude),
                   parseFloat(placemark.LookAt.longitude)],
        map_name: map.name
      };
      // Associate the trips made at this location.
      let trips = trip_index.filter((trip) => {
        if (Array.isArray(trip.location)) {
          // A trip may contain multiple locations.
          return trip.location.includes(obj.name);
        }
        return trip.location == obj.name;
      });
      if (trips.length > 0) {
        // Why put a location on the map if there are no associated trips?
        obj.trips = trips;
        data.push(obj);
      }
    });
  });
  fs.writeFileSync(output_json, JSON.stringify(data, null, 1));
}

I could go on...