Git Product home page Git Product logo

ghost-app's Introduction

The Ghost App module allows developers to build applications for the Ghost platform.

For more information please see: Getting Started with Apps for Ghost Devs

Development

Testing

  • yarn test to run tests
  • yarn coverage to run test coverage

Publish

  • yarn ship

Copyright & License

Copyright (c) 2013-2019 Ghost Foundation - Released under the MIT license. Ghost and the Ghost Logo are trademarks of Ghost Foundation Ltd. Please see our trademark policy for info on acceptable usage.

ghost-app's People

Contributors

aileen avatar brad avatar erisds avatar halfdan avatar jgable avatar johnonolan avatar kirrg001 avatar nchaulet avatar ttamminen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ghost-app's Issues

App Boilerplate: Do we need .App? and other extendable base apps?

Another discussion point.

At the moment, the first line of an app will look something like:

var App = require('ghost-app').App;

Arguably, it would be nicer to have:

var App = require('ghost-app');

However, the reason for the extra .App is the idea that we may have multiple base apps which you can extend to build an app. As per @jgable's original implementation, there were a number of potential examples such as FilterPlugin which has the addtitional syntax for registering filters mentioned in #6 and DatabasePlugin which has tools for adding and removing tables.

So the question is do we need these additional boilerplates? And if we do, do we always have to have .App or can we get around it?

In terms of the boilerplates, many of them are in place to do hardwork that the GDT should make much easier.. so perhaps they are less necessary.

On the flip-side, having boilerplates which provide structure and syntax for doing certain tasks is... well... epic! It is absolutely in line with most of our core principles for apps:

  • consistency, consistency, consistency
  • providing 1 clear way to do things
  • minimal boilerplate
  • sensible, manageable structure
  • easily extensible

Thoughts?

Switch to lodash

Would probably be smart to update the app to use lodash the same as the main app.

Accessing config inside custom application

Hello,

I need to access site global config inside app. How I can do this?

For example I need to access server.host variable depending on the NODE_ENV.

Thanks in advance,
Milos

App permission missing?

Possibly unhandled Error at Error.NoPermissionError (v:\weblapok\git\ghost.dev\Ghost.fork\core\server
\errors\no-permission-error.js:6:18)[..]
While I have all this shoved inside the app's package.json (tried to build a possible permissions page :) )..
My questoin is how to properly access the notifications api?
Regards,

"ghost": {
"permissions": {
"api.apps": ["browse", "read", "edit", "add", "delete"],
"api.authentication": ["browse", "read", "edit", "add", "destroy"],
"api.configuration": ["browse", "read", "edit", "add", "destroy"],
"api.db": ["exportContent", "importContent"],
"api.mail": ["browse", "read", "edit", "add", "destroy"],
"api.notifications": ["browse", "read", "add", "destroy", "destroyAll"],
"notifications": ["browse", "read", "add", "destroy", "destroyAll"],
"api.posts": ["browse", "read", "edit", "add", "destroy"],
"api.routes": ["browse", "read", "edit", "add", "destroy"],
"api.roles": ["browse", "read", "edit", "add", "destroy"],
"api.slugs": ["browse", "read", "edit", "add", "destroy"],
"api.tags": ["browse", "read", "edit", "add", "destroy"],
"api.themes": ["browse", "edit"],
"api.uploads": ["add"],
"api.settings": ["browse", "read", "edit", "add", "delete"],
"api.users": ["browse", "read", "edit", "add", "destroy"],
"helpers": ["browse", "read", "edit", "add", "destroy"],
"filters": ["ghost_head","ghost_foot"]
}
}

App Boilerplate: helpers

Want to leave this open whilst we're building out example apps and getting the platform into a usable state.

We have the backbone-events style JSON syntax for filters, would it make sense to add this for helpers too?

I'm referring to the ability to do:

MyApp = App.extend({
    helpers: {
       myHelper: 'myHelper'
    },
    myHelper: function () {},
});

I'm not sure if the same syntax makes sense, because the name of the helper is going to be the same as the name of the function. Also, how would we distinguish between async and non-async helpers?

Example Route App - Paypal Instant Notification

Trying to understand the docs, saw TryGhost/Ghost#6584

An overview of how apps appear to work now would be awesome...of course wouldn't come empty handed, here's the cut dry code works if added into /core/server/routes/frontend.js, api is required.

Adds paypal instant notifications to the ghost backend :)

var api = require('../api');
...

Should work if apps get to add their own routes...however that's done

        ...
    router.post('/paypal/notification/:sandbox', function(req, res){

        console.log('Received POST /');
        console.log(req.body);
        console.log('\n\n');

        // assign posted variables to local variables
        var item_name = req.body['item_name'];
        var item_number = req.body['item_number'];
        var payment_status = req.body['payment_status'];
        var payment_amount = req.body['mc_gross'];
        var payment_currency = req.body['mc_currency'];
        var txn_id = req.body['txn_id'];
        var receiver_email = req.body['receiver_email'];
        var payer_email = req.body['payer_email'];
        var payer_status = req.body['payer_status'];
        var address_status = req.body['address_status'];
        var first_name = req.body['first_name'];
        var last_name = req.body['last_name'];

        //var note = payer_email+' purchased '+item_name+'#'+item_number+' now '+payment_status+' for '+payment_amount+payment_currency;
        var note = payer_email+'<br>'+item_name+' #'+item_number+'<br>'+payment_status+'<br>'+payment_amount+payment_currency;

        var notetype = 'info';
        var status = payment_status.toUpperCase();

        if(status == "COMPLETED"){
            notetype = 'success';
        } 
        else if(status == "DENIED"){
            notetype = 'error';
        } 
        else if(status == "EXPIRED"){
            notetype = 'warn';
        } 
        else if(status == "FAILED"){
            notetype = 'error';
        }
        else if(status == "IN-PROGRESS"){
            notetype = 'info';
        }
        else if(status == "PARTIALLY_REFUNDED"){
            notetype = 'info';
        }
        else if(status == "PENDING"){
            notetype = 'info';
        }
        else if(status == "PROCESSED"){
            notetype = 'info';
        }
        else if(status == "REFUNDED"){
            notetype = 'warn';
        }
        else if(status == "REVERSED"){
            notetype = 'warn';
        }
        else if(status == "VOIDED"){
            notetype = 'warn';
        }
        else if(status == "CANCELED_REVERSAL"){
            notetype = 'warn';
        } else {
            notetype = 'info';
        }


        // type can be 'error', 'success', 'warn' and 'info'

        var notification = {
            type: notetype,
            message: note,
            location: 'top',
            dismissible: true
        };


        console.log("Adding note: "+note);

        var usernote = 'info';
        if(address_status.toUpperCase() == 'UNCONFIRMED'){
            usernote = 'warn';
        } else if(payer_status.toUpperCase() == 'UNVERIFIED'){
            usernote = 'warn';
        }

        api.notifications.add({notifications: [{
            type: usernote,
            message: first_name+' '+last_name+':'+payer_email+'<br>Address:'+address_status+'<br>Account:'+payer_status,
        }]}, {context: {internal: true}});

        api.notifications.add({notifications: [{
            type: notetype,
            message: note,
        }]}, {context: {internal: true}});

        console.log("Before send");

        // STEP 1: read POST data
        req.body = req.body || {};
        res.send(200, 'OK');
        res.end();

    });

Move Example-Apps repo into here (examples directory)

Why? It would be more maintainable in the long run.
They initially did the same thing over at rendr but it became a pain to keep the projects in sync. The main repo kept moving too fast and the example apps became neglected.

Normally I would say it's best to break things up into small projects but considering both these projects are quite simple combining them this way is unlikely to add to much complexity.

Adding routes

I've looked and I can't find a way to add a route through an app. Is this currently possible?

App Boilerplate: proxy object naming and structure

Whilst documenting how to get started with apps yesterday (see here), it occurred to me that this.app is perhaps not very semantic?

We already require('ghost-app'), which we then refer to in example code as App, and this makes sense, because you then call App.extend, to create a new app extending the base App class.

However, when you want to start talking to Ghost, which you do through the proxy, you have to do this.app.api.whatever, which is a bit odd. I think ghost.api or ghost.filters.registerFilters is more intuitive because it is Ghost I want to register a filter with, not the base app or my own app.

Additionally, the Ghost proxy is a static object that will not change between apps, or instances of apps. It is always the same. The functions themselves may return 401 / no permissions for different apps, but the actual functions will remain the same. Therefore it makes no sense to have lots of copies of it around if we can help it.

So I was wondering if, first we might want to rename this.app to this.ghost and second what can we do to make sure we use the proxy efficiently, both in the base App class and in the proxy itself?

Problem with node version

I use latest node (0.12.7) and npm v2.11.3. When I try to install ghost-app, I get following error:

npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install"
npm ERR! node v0.12.7
npm ERR! npm  v2.11.3
npm ERR! code ENOTSUP

npm ERR! notsup Unsupported
npm ERR! notsup Not compatible with your version of node/npm: [email protected]
npm ERR! notsup Required: {"node":"0.10.*"}
npm ERR! notsup Actual:   {"npm":"2.11.3","node":"0.12.7"}

Any ideas?

App Boilerplate: filters ?

This is intended as a discussion point.

Should filters be baked into the app boilerplate?

https://github.com/jgable/ghost-plugin/blob/master/lib/FilterPlugin.js

The idea ends up being much like defining events in Backbone. It's definitely a pretty awesome dev experience, and it makes a lot of sense. It looks like:

MyApp = App.extend({
    filters: {
      filterName: someFunction
    },

    someFunction: function (data) {
        // do something with data
        return data;
    }
});

Alternatively, should we have extend the base app boilerplate, and have a filter app boilerplate as in @jgable's original examples? I think filters are going to be common enough to warrant this neat syntax always being available.

Thoughts?

Setting up a new ghost app.

first issue :-)

So... I've been digging through the ghost source all day today trying to find a way to hook into the Posts array and only grab the main image of every post (Protip: there isn't one... As far as I can tell, anyway -- even though each post does, in fact, have an "image" property).
Anyway, at some point I stumbled onto this api feature, and now I'm here.
So hi.

How do I install an app I make?
I've read this
And I'm stuck on this because I am evidently so bad at sql, that I can't add an item to an array.

In
/content/data/blah.ghost.json
I see:

   {
        "id": 15,
        "uuid": "a number",
        "key": "activeApps",
        "value": "[]",
        "type": "app",
        "created_at": 1408810169322,
        "created_by": 1,
        "updated_at": 1408837881785,
        "updated_by": 1
      }

so I:

   {    
        "id" : 15,
        "key": "activeApps",
        "value": ["appName"],
    }

And that didn't... blow anything to pieces, but it still doesn't work-- or if it does, I can't figure out how to make it say so...
I stopped and restarted ghost.
Nothin.
Where am I going wrong?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.