Install Node.js and NPM (Node Package Manager). Then:
$ npm install -g grunt-cli
$ npm install
$ grunt init (and grunt prod if you want to run Ghost in production mode)
$ grunt dev
(make sure you're inside the directory when running the last 3 commands)
You will also need convert (ImageMagick) and gs (GhostScript) to generate images from the PDFs.
- Backend
- Run
grunt devfrom the root and start hackin - Learn to use the Node Debugger. You will be infinitely grateful.
- Run
- Frontend theme
- Go to
content/themes/hb_themeand rungrunt watch. This will watch for any changes in the SCSS and compile automatically. (i.e. You can just refresh the page to see your changes) - Use the Javascript debugger!
- Go to
The Hardboiled app is an augmented Ghost blog. Specifically, we've augmented it so that the Hardboiled team can publish their magazine issues directly through Ghost's CMS (Content Management System).
There are essentially three components to the Ghost app:
- An Ember JS app as the CMS for administrators and authors. This part is dynamic and routed mostly on the front-end.
- A static website for regular users to get content. The static site is themed.
- The backend: this includes a database, routes for the static frontend, an API to fetch data, and controllers to coerce the data into the right place and format for a user on the frontend using Ember's front-end router.
Here's the important part of the directory structure for the app. An explanation of the numbered items follows.
root .
1 ├── content
1 | ├── data
2 | ├── images
3 | ├── pdf
4 | └── themes
2 ├── core
1 | ├── built
2 | ├── client
1 | | ├── adapters
2 | | ├── assets
3 | | ├── components
4 | | ├── controllers
5 | | ├── helpers
6 | | ├── mixins
7 | | ├── models
8 | | ├── routes
9 | | ├── serializers
10 | | ├── templates
11 | | ├── validators
12 | | ├── views
13 | | └── router.js
3 | └── server
1 | ├── api
2 | ├── controllers/frontend.js
3 | ├── data
1 | | ├── schema.js
2 | | └── import
4 | ├── models
5 | ├── routes
6 | ├── search
7 | └── storage
3 ├── Gruntfile.js
4 ├── bower.json
5 ├── config.js
6 └── __cleanalldata.sh
Individual files are bolded, directories are not. Let me know if you have any questions.
contentDifferent kinds of static files.dataDatabase and other data for the application. Don't mess with this when in production.imagesStatic images served to blog. Images uploaded via the CMS get stored here.pdfStatic PDF files served to blog. PDFs uploaded via the CMS get stored here.themesTheme files for blog, written as Handlebars templates. Most of the frontend design work happens here.
coreThe "core" of the app. Almost all of the code lives here.builtCompiled Javascript+CSS+HTML files for dynamic CMS.clientAll code run on the client side (i.e. in the user's browser).adaptersContains adapters for query objects. When a model is queried from the database, its adapter will automagically "include" related models by checking its Ember Data type. For example, if a modeluserhas an embedded hasMany relation forrole, then querying for auserwill also query for therolesattached to that user.assetsStatic assets for dynamic Ember CMS app. Also includes logic for uploading images and pdfs.componentsReusable Ember Components for use in Handlebars templates.controllersControllers that feed data from the model associated with the route to the appropriate views and templates. Ember is an MVC framework; you should read the docs to understand this further.helpersTemplate helpers. These are sort of like reusable "functions" for displaying/retrieving/coercing the appropriate data for the template.mixinsMixins for views, controllers, and routes. If you haven't seen ES6 Javascript before, mixins are kind of like abstract classes that you can "include" into other classes.routesFront end routing JS specifically for Ember CMS app. Ember routing occurs on the front end only; these routes query the backend API using AJAX and other magic.serializersSerializers for models. Models are modified locally on the client's browser before being serialized and then saved to the backend database via an API call and an upload.templatesHandlebars templates specifically for the Ember CMS. Templates can be partial (i.e., there can be multiple templates rendered at a single route)validatorsFront-end validation for models before they are saved to database via API call.viewsEmber Views. These control the behavior the behavior of templates via Javascript.router.jsRouter for Ember CMS. New routes get defined here, routing logic lives in theroutesdirectory.
serverNode.js backend server logic. Nitty gritty stuff.apiAPI for querying/inserting/updating backend database. Defined per model, based on Ember Data.controllers/frontend.jsTies website frontend to backend data. When a user goes to the Hardboiled site, the queries and organizes all the data correctly to present to the frontend template (which is defined by the theme).dataDatabase magic.schema.jsSchema for models.importLogic for importing data from other blogs, like Wordpress.
modelsBackend representation of models. Built on Bookshelf.js and knex.js.routesActual routes for frontent, api, and admin (the last is the only one that has its own front-end router)searchUnfinished! Search logic. I recommend using one of the following search tools: norch, ghostHunter, or lunr.js. Of the three, I think the first is the best way to go, since it actually does indexing. The latter two build the entire search index on the front end everytime the user loads the website, so it's not scalable. :(storageLogic for saving static files to server filesystem on upload (not to the database).
Gruntfile.jsGruntfile. Read here.bower.jsonBower info and dependencies. Read here.package.jsonNodeJS info and dependencies.__cleanalldata.shWhipes the database. Useful for dev, but don't run this on prod!
I highly recommend going through the EmberJS tutorial. It may be tedious but you will be a thousand times more prepared to dive in and contribute. In general, reading the documentation for Ember and the other things I've linked above is key.
Things marked with <!!!> have higher priority. Permissions for Editor, Author, and User are only working on Ben's branch.
- <!!!> Search
- See
searchdirectory above. Check out norch, ghostHunter, or lunr.js. - I think the best way to handle this is to index all Issues, Articles, and Posts when they are saved to the database.
- See
- Populate issue title with series number (Ben)
- Magazines notification if one article is not existent
Permissions for Editor, Author, and User need to be tested.- <!!!> Need to be able to import data from Hardboiled Wordpress. (All posts and users)
- A lot of this has been done in this repo, but it's really slow and buggy right now. You'll need to get access to the Hardboiled Wordpress to be able to export their data (and then import it into Ghost).
Getting the first page of a PDF is SUPER hacky right now!!!I upload the PDF to Cloudinary because they have a nice API for getting images from PDF, and then query the image of the first page from there. THIS IS A TERRIBLE SOLUTION someone should fix this or just make HB upload the cover photo manually.Now generated via convert (ImageMagick)Username for Cloudinary account is[email protected]. Ask Maruchi for the password.
Posts need to be able to be marked as carousel-able.Their cover image should be displayed in the carousel on the front page.
- New Articles should take the status of the Issue that contains them automatically
- i.e., if an Issue is published, then new Articles added to that issue after the Issue has been published should be immediately published
We were originally using blog.ghost.org and Medium for inspiration/motivation.
-
Comments for posts! https://disqus.com/
-
Things that need to be styled: (Abhinav)
CMS for Issue and Article creationSidebar- Authors should have a little card with their info in their posts, articles, and search (scroll to bottom of this post)
- Tag and Author "search" pages
- Table of contents for Articles
-
An About Page for the Hardboiled Team (Robert, Magdalene, June Katherine)
- Like this but much more sexy with pictures and bios and pretty/interesting things.
- The About Page should be a static URL Post (probably).
-
The only "tabs" Hardboiled wants is Home, About, and Issues.
- Archived Issues on their current site becomes Issues for us.
- Web Exclusives are merged in as regular Posts.
- The Course tab from their current site becomes a hidden static page, only accessible via direct URL.
No Contact tab, just a footer.No explicit "Home" tab. Clicking on the HB logo brings you to Home page.