# Google Drive addon

**URL:** <https://discourse.getcockpit.com/t/google-drive-addon/1896>\
**Category:** Addons\
**Created:** [April 3, 2021, 1:50pm UTC](https://discourse.getcockpit.com/t/google-drive-addon/1896 "2021-04-03T13:50:55Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![VirHeroicus](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.getcockpit.com/virheroicus/32/807_2.png) [@VirHeroicus](https://discourse.getcockpit.com/u/VirHeroicus)\
**Post date:** [April 3, 2021, 1:50pm UTC](https://discourse.getcockpit.com/t/google-drive-addon/1896/1 "2021-04-03T13:50:55Z")

</div>

Hi there!  
I’m new to Cockpit, and currently setting up an addon to “integrate” Google Drive (dashboard widget / drive picker + services like uploading/retrieving files to/from google drive, generating/updating accouting Sheets; generating Google Docs from templates --like invoices…).

For now, I have two silly questions:

1/ how in all heavens do you make your additionnal assets (css and js) load and work?  
I’ve looked up how other addons did it; mimicked them; but for an unknown reason it’s not working on my side. I’m missing something obviously.

bootstrap.php:

```
$app->path('googledrive', 'addons/GoogleDrive/');
$this->module("cockpit")->extend([]);
include_once( __DIR__. '/admin.php');

```

in admin.php:

```
require_once( __DIR__. '/Controller/googleservices.php');

$app->on('admin.init', function() {}, 0);

$app->on("admin.dashboard.widgets", function($widgets) {

    if ($this->module('cockpit')->hasaccess('cockpit', 'GoogleDrive')) {
        $this->helper('admin')->addAssets('googledrive:assets/js/googledrive.js');
        $this->helper('admin')->addAssets('googledrive:assets/css/googledrive.css');
        $title = 'GoogleDrive yo';
        $gclient = new GoogleServices();
        $gat = $gclient->getgAccessToken();

        $widgets[] = [
            "name" => 'GoogleDrive',
            "content" => $this->view("googledrive:views/partials/widget.php", compact('title','gat')),
            "area" => 'main'
        ];
    }
}, 100);

$app('admin')->init();

```

I’ve tried direct url; I’ve tried adding @route… nothing works. 🧐

(I actually struggle quite a lot with routes; I wanted to make a proper “cockpit” class with `public function index()` but loading the Google Api from there would fail (bad route); so for now it’s just a good old `__construct()`…)

2/ How do you access data contained in a specific singleton? Do you make an… api call?  
Reasons: I would like to retrieve the google .json credentials file (service account) from a “user config” singleton. I would prefer to avoid the user to manually edit the config.yaml.

Thanks! 🙏

(I will obviously share the addon once done!)

---

<div class="post-metadata">

**Author:** ![raffaelj](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.getcockpit.com/raffaelj/32/331_2.png) [@raffaelj](https://discourse.getcockpit.com/u/raffaelj)\
**Post date:** [April 6, 2021, 1:06pm UTC](https://discourse.getcockpit.com/t/google-drive-addon/1896/2 "2021-04-06T13:06:46Z")

</div>

Hello @VirHeroicus,

> [@VirHeroicus](#):
>
> `$app->path('googledrive', 'addons/GoogleDrive/');`

You don’t need that line. Paths for addons/modules follow a naming pattern. Let’s assume the following folder structure:

```plaintext
.
├── addons/
│ └── GoogleDriveConnector/
│ ├── assets/
│ | ├── style.css
│ | └── script.js
│ ├── Controller/
│ | └── Admin.php
│ ├── Helper/
│ ├── views/
│ | └── index.php
│ ├── bootstrap.php
│ └── admin.php

```

For `$app->path()`, the folder name is case insensitive. For Controllers and Helpers (classes), proper casing is mandatory.

```php
$path = $app->path('googledriveconnector:views/index.php');
# /var/www/virtual/user/html/addons/GoogleDriveConnector/views/index.php

$path = $app->pathToUrl('googledriveconnector:views/index.php');
# /addons/GoogleDriveConnector/views/index.php

```

The Admin controller can be autoloaded.

**Controller/Admin.php:**

```php
<?php

// must match the folder name!
namespace GoogleDriveConnector\Controller;

class Admin extends \Cockpit\AuthController {

    public $data = [
        'don\'t be evil' => false,
        'GDPR-compliant' => false,
        'spyware' => 'kind of',
        'alternatives' => [
            'Drive' => ['Nextcloud'],
            'Docs' => ['Etherpad', 'OnlyOffice'],
        ],
    ]

    public function index() {

        return $this->render('googledriveconnector:views/index.php', ['data' => $this->data]);

    }

    public function getData() {

        return $this->data;

    }

}

```

**admin.php:**

```php
<?php

$this->on('admin.init', function() {

    // add assets
    $this->helper('admin')->addAssets([
        'googledriveconnector:assets/style.css',
        'googledriveconnector:assets/script.js',
    ]);

    // bind admin routes
    // --> "/gdc" points to index()
    // --> "/gdc/getData" points to getData()
    $this->bindClass('GoogleDriveConnector\\Controller\\Admin', 'gdc');

});

```

> [@VirHeroicus](#):
>
> 1/ how in all heavens do you make your additionnal assets (css and js) load and work?

see above

> [@VirHeroicus](#):
>
> `include_once( __DIR__. '/admin.php');`

Code inside `admin.php` is only for backend access, so don’t load it if you don’t need it. The name has nothing to do with the “admin” group permission.

```php
if (COCKPIT_ADMIN_CP) include_once( __DIR__. '/admin.php');

```

> [@VirHeroicus](#):
>
> `$app->on("admin.dashboard.widgets", function($widgets) {`

Don’t start with widgets, if you want to learn Cockpit. Create pages and routes, call them directly in your browser to see the json responses. If your core logic works, think about widgets. Be aware, that widgets have a drag event by default.

> [@VirHeroicus](#):
>
> 2/ How do you access data contained in a specific singleton? Do you make an… api call?

```php
$config = $app->module('singletons')->getData('name-of-singleton');

```

see: [https://github.com/agentejo/cockpit/blob/next/modules/Singletons/bootstrap.php#L136](https://github.com/agentejo/cockpit/blob/next/modules/Singletons/bootstrap.php#L136)

**Further notes:**

It looks like you used the Groups addon for inspiration. It isn’t very well structured (at least to get started). I think, this one is easier for understanding the folder and path structure:

> **[GitHub - raffaelj/cockpit\_ImageResize: Addon for Cockpit CMS to resize...](https://github.com/raffaelj/cockpit_ImageResize)**
>
> Addon for Cockpit CMS to resize uploaded images automatically - GitHub - raffaelj/cockpit\_ImageResize: Addon for Cockpit CMS to resize uploaded images automatically

**More resources:**

> [@How to create a addon](https://discourse.getcockpit.com/t/how-to-create-a-addon/345/6):
>
> Cockpit has a lot of ways to get modified. A few of them are documented. If you read anything in the issues or in this forum about adding code to config/bootstrap.php, this same code could be in an addon with the same effect. The difference here is, if you want to modify it fast and simple or if you want to provide a reusable addon. Addons are handled the same like core modules (collections, singletons, forms). So, each addon will be auto-registered as a cockpit module. Theoretically, there is …

> <https://github.com/agentejo/cockpit/blob/next/lib/Lime/App.php#L1106-L1137>

> <https://github.com/agentejo/cockpit/blob/next/lib/Lime/App.php#L118-L130>

> <https://github.com/agentejo/cockpit/blob/next/lib/Lime/App.php#L352-L391>

---

<div class="post-metadata">

**Author:** ![VirHeroicus](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.getcockpit.com/virheroicus/32/807_2.png) [@VirHeroicus](https://discourse.getcockpit.com/u/VirHeroicus)\
**Post date:** [April 10, 2021, 2:31pm UTC](https://discourse.getcockpit.com/t/google-drive-addon/1896/3 "2021-04-10T14:31:47Z")

</div>

Thank you for your very extensive answer.

---

<div class="post-metadata">

**Author:** ![drascom](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.getcockpit.com/drascom/32/718_2.png) [@drascom](https://discourse.getcockpit.com/u/drascom)\
**Post date:** [April 29, 2021, 6:05pm UTC](https://discourse.getcockpit.com/t/google-drive-addon/1896/4 "2021-04-29T18:05:32Z")

</div>

we are waiting first working version for testing.good to see people trying to improve…
