Electron + WordPress = ❤

117
Electron + WordPress = Tomasz Dziuda

Transcript of Electron + WordPress = ❤

Page 1: Electron + WordPress = ❤

Electron + WordPress = Tomasz Dziuda

Page 2: Electron + WordPress = ❤

Dlaczego?

Page 3: Electron + WordPress = ❤

Umiem w Electrony...Źródło: https://getpublii.com

Page 4: Electron + WordPress = ❤

w WordPressy trochę też ...

Page 5: Electron + WordPress = ❤

coraz bardziej cenię swoją prywatność

Page 6: Electron + WordPress = ❤

Czego użyjemy?

Page 7: Electron + WordPress = ❤
Page 8: Electron + WordPress = ❤

Przyśpieszony Kurs Electrona

Page 9: Electron + WordPress = ❤

Źródło: https://atom.io/

Page 10: Electron + WordPress = ❤

Źródło: https://desktop.github.com/

Page 11: Electron + WordPress = ❤

=

Przyśpieszony Kurs Electrona

Page 12: Electron + WordPress = ❤

=

Przyśpieszony Kurs Electrona

Page 13: Electron + WordPress = ❤

= +

Przyśpieszony Kurs Electrona

Page 14: Electron + WordPress = ❤

= + +

Przyśpieszony Kurs Electrona

Page 15: Electron + WordPress = ❤

Przyśpieszony Kurs Electrona cz.2

Wątek główny

Page 16: Electron + WordPress = ❤

Przyśpieszony Kurs Electrona cz.2

Wątek główny

API systemu

Page 17: Electron + WordPress = ❤

Przyśpieszony Kurs Electrona cz.2

...Wątki renderujące

Wątek główny

API systemu

Page 18: Electron + WordPress = ❤

Przyśpieszony Kurs Electrona cz.2

...Wątki renderujące

Wątek główny

API systemu

IPC IPC IPC

Page 19: Electron + WordPress = ❤

Przyśpieszony Kurs Electrona cz.3

Build cross platform desktop apps with JavaScript, HTML, and CSS

Page 20: Electron + WordPress = ❤

Przyśpieszony Kurs Electrona cz.3

Build cross platform desktop apps with JavaScript, HTML, and CSS

XSS

Page 21: Electron + WordPress = ❤

Przyśpieszony Kurs Electrona cz.4

Brak możliwości ukrycia kodu źródłowego

Page 22: Electron + WordPress = ❤

Dlaczego WordPress?

Page 23: Electron + WordPress = ❤

Gotowe REST API

{REST API}GET POST PUT DELETE

Page 24: Electron + WordPress = ❤

Gotowy panel zarządzania

Page 25: Electron + WordPress = ❤

Źródło: https://www.contentful.com/

Page 26: Electron + WordPress = ❤

Połowa pracy za nami a jeszcze nie zaczęliśmy ;-)

Page 27: Electron + WordPress = ❤

1 WordPress = wiele aplikacji

Page 28: Electron + WordPress = ❤

Dlaczego React?

Page 29: Electron + WordPress = ❤

JSX

<App> <Header /> <Content /> <Footer /> <Sidebar /></App>

Page 30: Electron + WordPress = ❤

Ekosystem

Page 31: Electron + WordPress = ❤

Używają go w Automattic ;-)Źródło: https://developer.wordpress.com/calypso/

Page 32: Electron + WordPress = ❤

Przydatne narzędzia...mi pomogły ;-)

Page 33: Electron + WordPress = ❤

Postman

Źródło: https://www.getpostman.com/

Page 34: Electron + WordPress = ❤

Devtron

Źródło: https://electron.atom.io/devtron/

Page 35: Electron + WordPress = ❤

Założenia

Page 36: Electron + WordPress = ❤

WP Notes

Page 37: Electron + WordPress = ❤

WP Notes• Synchronizacja notatek po uruchomieniu/zalogowaniu

• Obsługa wielu użytkowników

• Edytor Markdown

• Możliwość dodawania, edycji i usuwania notatek

• Wyszukiwarka notatek

Page 38: Electron + WordPress = ❤

WP Notes• Synchronizacja notatek po uruchomieniu/zalogowaniu

• Obsługa wielu użytkowników

• Edytor Markdown

• Możliwość dodawania, edycji i usuwania notatek

• Wyszukiwarka notatek

Page 39: Electron + WordPress = ❤

WP Notes• Synchronizacja notatek po uruchomieniu/zalogowaniu

• Obsługa wielu użytkowników

• Edytor Markdown

• Możliwość dodawania, edycji i usuwania notatek

• Wyszukiwarka notatek

Page 40: Electron + WordPress = ❤

WP Notes• Synchronizacja notatek po uruchomieniu/zalogowaniu

• Obsługa wielu użytkowników

• Edytor Markdown

• Możliwość dodawania, edycji i usuwania notatek

• Wyszukiwarka notatek

Page 41: Electron + WordPress = ❤

WP Notes• Synchronizacja notatek po uruchomieniu/zalogowaniu

• Obsługa wielu użytkowników

• Edytor Markdown

• Możliwość dodawania, edycji i usuwania notatek

• Wyszukiwarka notatek

Page 42: Electron + WordPress = ❤

Implementacja

Page 43: Electron + WordPress = ❤

Składowe

Page 44: Electron + WordPress = ❤

Składowe

Odpowiednie endpointy REST API Plugin + CPT

Page 45: Electron + WordPress = ❤

Składowe

Odpowiednie endpointy REST API

Autoryzacja komunikacji

Plugin + CPT

JWT

Page 46: Electron + WordPress = ❤

Składowe

Odpowiednie endpointy REST API

Autoryzacja komunikacji

Aplikacja napisana w Electronie

Plugin + CPT

JWT

Electron + React

Page 47: Electron + WordPress = ❤

Endpointy i CPT

Page 48: Electron + WordPress = ❤

Plugin dla aplikacji

Page 49: Electron + WordPress = ❤

Plugin dla aplikacji

• Tworzy dedykowany Custom Post Type dla danych

• Tworzy potrzebne endpointy

• Modyfikuje istniejące endpointy

Page 50: Electron + WordPress = ❤

Plugin dla aplikacji

• Tworzy dedykowany Custom Post Type dla danych

• Tworzy potrzebne endpointy

• Modyfikuje istniejące endpointy

Page 51: Electron + WordPress = ❤

Plugin dla aplikacji

• Tworzy dedykowany Custom Post Type dla danych

• Tworzy potrzebne endpointy

• Modyfikuje istniejące endpointy

Page 52: Electron + WordPress = ❤

Dlaczego Custom Post Type?

Page 53: Electron + WordPress = ❤

Dlaczego Custom Post Type?

• Możemy na jednym WordPressie oprzeć kilka aplikacji

• CPT mogą mieć własne endpointy

• Możemy te endpointy bez obaw dostosować do swoich potrzeb

Page 54: Electron + WordPress = ❤

Dlaczego Custom Post Type?

• Możemy na jednym WordPressie oprzeć kilka aplikacji

• CPT mogą mieć własne endpointy

• Możemy te endpointy bez obaw dostosować do swoich potrzeb

Page 55: Electron + WordPress = ❤

Dlaczego Custom Post Type?

• Możemy na jednym WordPressie oprzeć kilka aplikacji

• CPT mogą mieć własne endpointy

• Możemy te endpointy bez obaw dostosować do swoich potrzeb

Page 56: Electron + WordPress = ❤

Endpointy

Page 57: Electron + WordPress = ❤

/wp-json/wp/v2/wp-notes

$args = array(// ...'show_in_rest' => true,'rest_base' => 'wp-notes'

);

register_post_type( 'wp_notes', $args );

Page 58: Electron + WordPress = ❤

/wp-json/wp-notes/v1/notes?author=X

[ { "id": 36, "modificationDate": 1495370276000 }, ... { "id": 13, "modificationDate": 1495295589000 }, { "id": 9, "modificationDate": 1495368831000 }]

https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/

Page 59: Electron + WordPress = ❤

Posty prywatne są przydatne ;)

Page 60: Electron + WordPress = ❤

Pobieranie prywatnych postów

1) Musimy być autoryzowani jako twórca wpisu

2) W URL-u REST API dodajemy:

wp-json/wp/v2/wp-notes/?status=private

Page 61: Electron + WordPress = ❤

Pamiętajmy o strefach czasowych

CEST UTC

:-(

Page 62: Electron + WordPress = ❤

[ { ... "date_gmt": "2017-05-21T12:37:56", ... "modified_gmt": "2017-05-21T12:37:56", ... }]

new Date().getTime() // Zwraca czas UTC

Page 63: Electron + WordPress = ❤

Modyfikacje endpointów

Page 64: Electron + WordPress = ❤

function dziudek_wp_notes_use_raw_content( $data, $post, $request ) { $data->data['content']['plaintext'] = $post->post_content; $data->data['title']['plaintext'] = $post->post_title; $data->data['modified_gmt'] = strtotime($post->post_modified_gmt . ' UTC') * 1000; return $data;}

add_filter( 'rest_prepare_wp_notes', 'dziudek_wp_notes_use_raw_content', 10, 3 );

Page 65: Electron + WordPress = ❤

function dziudek_wp_notes_use_raw_content( $data, $post, $request ) { $data->data['content']['plaintext'] = $post->post_content; $data->data['title']['plaintext'] = $post->post_title; $data->data['modified_gmt'] = strtotime($post->post_modified_gmt . ' UTC') * 1000; return $data;}

add_filter( 'rest_prepare_wp_notes', 'dziudek_wp_notes_use_raw_content', 10, 3 );

Page 66: Electron + WordPress = ❤

function dziudek_wp_notes_use_raw_content( $data, $post, $request ) { $data->data['content']['plaintext'] = $post->post_content; $data->data['title']['plaintext'] = $post->post_title; $data->data['modified_gmt'] = strtotime($post->post_modified_gmt . ' UTC') * 1000; return $data;}

add_filter( 'rest_prepare_wp_notes', 'dziudek_wp_notes_use_raw_content', 10, 3 );

Page 67: Electron + WordPress = ❤

function dziudek_wp_notes_use_raw_content( $data, $post, $request ) { $data->data['content']['plaintext'] = $post->post_content; $data->data['title']['plaintext'] = $post->post_title; $data->data['modified_gmt'] = strtotime($post->post_modified_gmt . ' UTC') * 1000; return $data;}

add_filter( 'rest_prepare_wp_notes', 'dziudek_wp_notes_use_raw_content', 10, 3 );

Page 68: Electron + WordPress = ❤

Autoryzacja

Page 69: Electron + WordPress = ❤

Źródło: https://jwt.io/

Page 70: Electron + WordPress = ❤

Źródło: https://jwt.io/

Page 71: Electron + WordPress = ❤

Dane w tokenie NIE SĄ szyfrowane

Page 72: Electron + WordPress = ❤

Przy komunikacji z REST API korzystaj z połączenia SSL

Page 73: Electron + WordPress = ❤

Źródło: https://pl.wordpress.org/plugins/jwt-authentication-for-wp-rest-api/

Page 74: Electron + WordPress = ❤

Gdy JWT nie działają dodaj w .htaccess:

RewriteEngine onRewriteCond %{HTTP:Authorization} ^(.*)RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

Czasem może też być potrzebne dodanie:

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

Page 75: Electron + WordPress = ❤

Autoryzacja - krok 1Wysyłamy zapytaniem POST do endpointa /wp-json/jwt-auth/v1/token login i hasło użytkownika, którego chcemy autoryzować:

{ username: 'admin', password: 'password'}

Page 76: Electron + WordPress = ❤

Autoryzacja - krok 1Wysyłamy zapytaniem POST do endpointa /wp-json/jwt-auth/v1/token login i hasło użytkownika, którego chcemy autoryzować:

{ username: 'admin', password: 'password'}

{ "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ...", "user_display_name": "admin", "user_email": "[email protected]", "user_nicename": "admin"}

Gdy dane są poprawne otrzymujemy token i dane użytkownika:

Page 77: Electron + WordPress = ❤

Autoryzacja - krok 2

Do każdego zapytania wymagającego autoryzacji dodajemy nagłówek:

Authorization: Bearer WARTOŚĆ_TOKENA

Page 78: Electron + WordPress = ❤

Aplikacja

Page 79: Electron + WordPress = ❤

Struktura aplikacji

<App>

Page 80: Electron + WordPress = ❤

Struktura aplikacji

<App>

<Editor><Sidebar>

Page 81: Electron + WordPress = ❤

Struktura aplikacji

<App>

<Editor><Sidebar>

<Search>

<List><ReactMarkdown>

Page 82: Electron + WordPress = ❤

Struktura aplikacji

<App>

<Editor><Sidebar>

<Search>

<List>

<Item>

<ReactMarkdown>

<Item>

<Item>

Page 83: Electron + WordPress = ❤

Komunikacja pomiędzy komponentami

Page 84: Electron + WordPress = ❤

Wzorzec obserwatoraclass EventEmitter extends React.Component { dispatch(event, data) { ... } subscribe(event, callback) { ... } unsubscribe(event, callback) { ... }}

Page 85: Electron + WordPress = ❤

Wzorzec obserwatoraclass EventEmitter extends React.Component { dispatch(event, data) { ... } subscribe(event, callback) { ... } unsubscribe(event, callback) { ... }}

Page 86: Electron + WordPress = ❤

Wzorzec obserwatoraclass EventEmitter extends React.Component { dispatch(event, data) { ... } subscribe(event, callback) { ... } unsubscribe(event, callback) { ... }}

Page 87: Electron + WordPress = ❤

Wzorzec obserwatoraclass EventEmitter extends React.Component { dispatch(event, data) { ... } subscribe(event, callback) { ... } unsubscribe(event, callback) { ... }}

Page 88: Electron + WordPress = ❤

Wzorzec obserwatoraclass EventEmitter extends React.Component { dispatch(event, data) { ... } subscribe(event, callback) { ... } unsubscribe(event, callback) { ... }}

class App extends React.Component

class App extends EventEmitter

Page 89: Electron + WordPress = ❤

Wzorzec obserwatoraclass EventEmitter extends React.Component { dispatch(event, data) { ... } subscribe(event, callback) { ... } unsubscribe(event, callback) { ... }}

class App extends React.Component

class App extends EventEmitter

Page 90: Electron + WordPress = ❤

<App>

<Editor><Sidebar>

<Search>

<List>

<Item>

<ReactMarkdown>

<Item>

<Item>

Page 91: Electron + WordPress = ❤

<App>

<Editor><Sidebar>

<Search>

<List>

<Item>

<ReactMarkdown>

<Item>

<Item>

Page 92: Electron + WordPress = ❤

<App>

<Editor><Sidebar>

<Search>

<List>

<Item>

<ReactMarkdown>

<Item>

<Item>

subscribe('delete-item', callback)

Page 93: Electron + WordPress = ❤

<App>

<Editor><Sidebar>

<Search>

<List>

<Item>

<ReactMarkdown>

<Item>

<Item>

distpatch('delete-item', itemID)

Page 94: Electron + WordPress = ❤

Przechowywanie danych

Page 95: Electron + WordPress = ❤

Przechowywanie danychuser_ID_1 1.md 2.md 3.md files.json

user_ID_2 4.md 5.md files.json

Page 96: Electron + WordPress = ❤

Przechowywanie danychuser_ID_1 1.md 2.md 3.md files.json

user_ID_2 4.md 5.md files.json

Page 97: Electron + WordPress = ❤

[ {

id: 10, title: "Post title", modificationDate: 123049044

}, {

id: 10, title: "Post title", modificationDate: 123049044

}, ...

]

Przechowywanie danychfiles.jsonuser_ID_1

1.md 2.md 3.md files.json

user_ID_2 4.md 5.md files.json

Page 98: Electron + WordPress = ❤

Synchronizacja danych

Page 99: Electron + WordPress = ❤

Pobranie danych z endpointa synchronizacji

dziudek-wp-notes/1/ 1.md 2.md 3.md files.json

[{"id": 1,"modificationDate": 102

}, {"id": 4,"modificationDate": 105

}]

wp-json/wp-notes/v1/notes?author=1

Page 100: Electron + WordPress = ❤

Porównanie dat modyfikacji postów

[{"id": 1,"modificationDate": 102

}, {"id": 4,"modificationDate": 105

}]

[{"id": 1,"modificationDate": 101

}, {"id": 2,"modificationDate": 102

},{"id": 3,"modificationDate": 103

}]

Lokalnie Zdalnie

Page 101: Electron + WordPress = ❤

Usunięcie nieistniejących plików

dziudek-wp-notes/1/ 1.md 2.md 3.md files.json

[{"id": 1,"modificationDate": 102

}, {"id": 4,"modificationDate": 105

}]

Page 102: Electron + WordPress = ❤

Pobranie i zaktualizowanie zmienionych wpisów

dziudek-wp-notes/1/ 1.md 4.md files.json

[{"id": 1,"modificationDate": 102

}, {"id": 4,"modificationDate": 105

}]

Page 103: Electron + WordPress = ❤

Zaktualizowanie pliku files.json

dziudek-wp-notes/1/ 1.md 4.md files.json

[{"id": 1,"modificationDate": 102

}, {"id": 4,"modificationDate": 105

}]

Page 104: Electron + WordPress = ❤

Pobieranie danych: node-fetch

Źródło: https://github.com/bitinn/node-fetch

Fetch API: https://developers.google.com/web/updates/2015/03/introduction-to-fetch

fetch('http://httpbin.org/post', { method: 'POST', body: stream }) .then(res => res.json()) .then(json => console.log(json));

Page 105: Electron + WordPress = ❤

Edytor

Źródło: https://github.com/JedWatson/react-md-editor

render: function() {return <Editor

value={this.state.code} options={configObject} onChange={this.updateCode} />

}

Page 106: Electron + WordPress = ❤

Źródło: https://codemirror.net/

Page 107: Electron + WordPress = ❤

Skróty klawiaturoweimport {remote} from 'electron';

const template = [{ label: "Edit", submenu: [{ label: "Zapisz zmiany", accelerator: "CmdOrCtrl+S", click: function() { // .. } ]}];

const menu = remote.Menu.buildFromTemplate(template);remote.Menu.setApplicationMenu(menu);

Page 108: Electron + WordPress = ❤

DEMO

Page 109: Electron + WordPress = ❤
Page 110: Electron + WordPress = ❤

Co dalej?

Page 111: Electron + WordPress = ❤

Offline mode

Page 112: Electron + WordPress = ❤

Generowanie PDF-ówlet win = new BrowserWindow({width: 800, height: 600})win.loadURL('file://file-to-load.html')

win.webContents.on('did-finish-load', () => { win.webContents.printToPDF({}, (error, data) => { fs.writeFile('/tmp/print.pdf', data, (error) => { console.log('Write PDF successfully.') }); });});

Page 113: Electron + WordPress = ❤

Bezpieczne przechowywanie tokenów

Page 114: Electron + WordPress = ❤

node-keytar

Źródło: http://atom.github.io/node-keytar/

Natywny moduł do przechowywania haseł z użyciem Keychain (macOS),

Credential Vault (Windows) i libsecret (Linux)

Page 115: Electron + WordPress = ❤

Do przejrzenia

• https://nodesource.com/blog/fifteen-essential-packages-to-get-started-with-electron/

• https://openfin.co/2016/11/04/openfin-slashes-electron-memory-78/

• http://blog.atom.io/2017/04/18/improving-startup-time.html

• https://openfin.co/2016/02/17/openfin-addressing-security-and-performance-challenges-with-electron/

• https://github.com/pojala/electrino

• https://github.com/MacGapProject/MacGap1

Plugin: https://github.com/dziudek/WordCampPolska-WP-Notes-Plugin

Aplikacja: https://github.com/dziudek/WordCampPolska-WP-Notes-App

Artykuły warte uwagi:

Page 116: Electron + WordPress = ❤

Pytania?

Page 117: Electron + WordPress = ❤

[email protected]

@dziudek

http://dziudek.pl

http://www.slideshare.net/dziudek

Tomasz Dziuda