WP-API
teoria i praktyka
Tomasz Dziuda
WordUp Łódź #4 10.VI.2015
Idea
+
WP-API
GET/POST/PUT/DELETE
+
WP-API
GET/POST/PUT/DELETE
{“json”: “data”}
+
WP-API
GET/POST/PUT/DELETE
{“json”: “data”}
wp_ajax_{action}
wp_ajax_nopriv_{action}
+
WP-API
GET/POST/PUT/DELETE
{“json”: “data”}
wp_ajax_{action}
wp_ajax_nopriv_{action}
+
WP-API
Struktura URLi
wp-json/<zasób>/<id_lub_filtr>/<dodatkowe_zasoby>
/
/posts
/posts/<id>/meta
/posts/<id>/revisions
/media
/users
/taxonomies
/taxonomies/<taxonomy>/terms
Przykłady
Przykłady
• wp-json/posts/303
• wp-json/posts?filter[cat]=1,2,3
• wp-json/posts?filter[posts_per_page]=20
• Więcej filtrów: http://wp-api.org/#posts_retrieve-posts
• wp-json/taxonomies/category/terms
• wp-json/users/me
Przykłady
• wp-json/posts/303
• wp-json/posts?filter[cat]=1,2,3
• wp-json/posts?filter[posts_per_page]=20
• Więcej filtrów: http://wp-api.org/#posts_retrieve-posts
• wp-json/taxonomies/category/terms
• wp-json/users/me
Przykłady
• wp-json/posts/303
• wp-json/posts?filter[cat]=1,2,3
• wp-json/posts?filter[posts_per_page]=20
• Więcej filtrów: http://wp-api.org/#posts_retrieve-posts
• wp-json/taxonomies/category/terms
• wp-json/users/me
Przykłady
• wp-json/posts/303
• wp-json/posts?filter[cat]=1,2,3
• wp-json/posts?filter[posts_per_page]=20
• Więcej filtrów: http://wp-api.org/#posts_retrieve-posts
• wp-json/taxonomies/category/terms
• wp-json/users/me
Przykłady
• wp-json/posts/303
• wp-json/posts?filter[cat]=1,2,3
• wp-json/posts?filter[posts_per_page]=20
• Więcej filtrów: http://wp-api.org/#posts_retrieve-posts
• wp-json/taxonomies/category/terms
• wp-json/users/me
Przykłady
• wp-json/posts/303
• wp-json/posts?filter[cat]=1,2,3
• wp-json/posts?filter[posts_per_page]=20
• Więcej filtrów: http://wp-api.org/#posts_retrieve-posts
• wp-json/taxonomies/category/terms
• wp-json/users/me
GET / HEAD - odczyt istniejącego elementu
POST - tworzenie nowego elementu
PUT / PATCH - edycja elementu
DELETE - usunięcie elementu
GET / HEAD - odczyt istniejącego elementu
POST - tworzenie nowego elementu
PUT / PATCH - edycja elementu
DELETE - usunięcie elementu
GET / HEAD - odczyt istniejącego elementu
POST - tworzenie nowego elementu
PUT / PATCH - edycja elementu
DELETE - usunięcie elementu
GET / HEAD - odczyt istniejącego elementu
POST - tworzenie nowego elementu
PUT / PATCH - edycja elementu
DELETE - usunięcie elementu
GET / HEAD - odczyt istniejącego elementu
POST - tworzenie nowego elementu
PUT / PATCH - edycja elementu
DELETE - usunięcie elementu
Wymagają zawsze autoryzacji
Wymagają CZASAMI autoryzacji
JSON jako nośnik danych
JSON jako nośnik danych
• Zajmuje mniej miejsca niż XML
• Można go łatwiej przetwarzać z użyciem JavaScript
• http://www.json.org/xml.html
JSON jako nośnik danych
• Zajmuje mniej miejsca niż XML
• Można go łatwiej przetwarzać z użyciem JavaScript
• http://www.json.org/xml.html
JSON jako nośnik danych
• Zajmuje mniej miejsca niż XML
• Można go łatwiej przetwarzać z użyciem JavaScript
• http://www.json.org/xml.html
Wtyczka JSON Viewer: https://chrome.google.com/webstore/detail/json-viewer/
gbmdgpbipfallnflgajpaliibnhdgobh/
Akcje wymagające
autoryzacji
• Tworzenie i modyfikacja postów
• Odczyt rewizji postów
• Tworzenie załączników
• Tworzenie, modyfikacja, odczyt post meta
• Tworzenie, modyfikacja, odczyt użytkowników
Sposoby autoryzacji
Cookie Auth
• Standardowa metoda autoryzacji dla wtyczek i
motywów
• Wymaga przesłania w zapytaniu AJAX-owym
dodatkowego nagłówka X-WP-Nonce

http://wp-api.org/guides/authentication.html#cookie-authentication
Cookie Auth
• Standardowa metoda autoryzacji dla wtyczek i
motywów
• Wymaga przesłania w zapytaniu AJAX-owym
dodatkowego nagłówka X-WP-Nonce

http://wp-api.org/guides/authentication.html#cookie-authentication
OAuth
• Dla aplikacji zewnętrznych - webowych, mobilnych,
desktopowych
• Wymaga dodatkowego pluginu - OAuth Server

https://github.com/WP-API/OAuth1
• Wsparcie tylko dla OAuth 1.*
• Niestety obecnie nie ma UI do zarządzania
kluczami
OAuth
• Dla aplikacji zewnętrznych - webowych, mobilnych,
desktopowych
• Wymaga dodatkowego pluginu - OAuth Server

https://github.com/WP-API/OAuth1
• Wsparcie tylko dla OAuth 1.*
• Niestety obecnie nie ma UI do zarządzania
kluczami
OAuth
• Dla aplikacji zewnętrznych - webowych, mobilnych,
desktopowych
• Wymaga dodatkowego pluginu - OAuth Server

https://github.com/WP-API/OAuth1
• Wsparcie tylko dla OAuth 1.*
• Niestety obecnie nie ma UI do zarządzania
kluczami
OAuth
• Dla aplikacji zewnętrznych - webowych, mobilnych,
desktopowych
• Wymaga dodatkowego pluginu - OAuth Server

https://github.com/WP-API/OAuth1
• Wsparcie tylko dla OAuth 1.*
• Niestety obecnie nie ma UI do zarządzania
kluczami
Basic Auth
• Tylko do środowisk testowych, istnieje duże ryzyko
wycieku hasła wskutek braku szyfrowania
• Wymaga dodatkowej wtyczki: Basic Auth

https://github.com/WP-API/Basic-Auth
Basic Auth
• Tylko do środowisk testowych, istnieje duże ryzyko
wycieku hasła wskutek braku szyfrowania
• Wymaga dodatkowej wtyczki: Basic Auth

https://github.com/WP-API/Basic-Auth
Własne metody
• Wymagają implementacji z użyciem filtra
json_authentication_errors

https://apppresser.com/custom-wp-api-authentication/
• Można zaimplementować np. JSON Web Tokens

http://jwt.io/
Własne metody
• Wymagają implementacji z użyciem filtra
json_authentication_errors

https://apppresser.com/custom-wp-api-authentication/
• Można zaimplementować np. JSON Web Tokens

http://jwt.io/
Możliwości
Nowe kokpity
Źródło: https://pickle.pub/
Źródło: https://dribbble.com/shots/2056289-WordPress-Dashboard/attachments/367241
Panele zarządzania
WordPressami
Źródło: https://wordpress.com/sites
Motywy jako SPA
Łatwa komunikacja z
aplikacjami
Migrowanie danych
Migrowanie danych
Migrowanie danych
JSON
XML
SQL
YAML
RSS
Atom
Migrowanie danych
JSON
JSON
XML
SQL
YAML
RSS
Atom
Przetwarzanie danych
Przetwarzanie danych
JSON
Przetwarzanie danych
JSON
Przetwarzanie danych
Rozszerzenia przeglądarek
zintegrowane z WordPressem
Usługi informacyjne
Kalendarz WordUpów
Kalendarz WordUpów
• Przygotowujemy WordPressa z listą WordUpów
• Tworzymy odpowiednie custom fields opisujące
WordUpy
• Tworzymy widżet, który pobiera te informacje
• Wykorzystujemy HTTP API albo JSON-P



https://codex.wordpress.org/HTTP_API

http://json-p.org/

Kalendarz WordUpów
• Przygotowujemy WordPressa z listą WordUpów
• Tworzymy odpowiednie custom fields opisujące
WordUpy
• Tworzymy widżet, który pobiera te informacje
• Wykorzystujemy HTTP API albo JSON-P



https://codex.wordpress.org/HTTP_API

http://json-p.org/

Kalendarz WordUpów
• Przygotowujemy WordPressa z listą WordUpów
• Tworzymy odpowiednie custom fields opisujące
WordUpy
• Tworzymy widżet, który pobiera te informacje
• Wykorzystujemy HTTP API albo JSON-P



https://codex.wordpress.org/HTTP_API

http://json-p.org/

Kalendarz WordUpów
• Przygotowujemy WordPressa z listą WordUpów
• Tworzymy odpowiednie custom fields opisujące
WordUpy
• Tworzymy widżet, który pobiera te informacje
• Wykorzystujemy HTTP API albo JSON-P



https://codex.wordpress.org/HTTP_API

http://json-p.org/

Własne end-pointy
http://wp-api.org/guides/extending.html
http://www.roysivan.com/my-best-practices-to-developing-wp-api/
Filtry i akcje
Moje dwa ulubione filtry:
• json_insert_post - pozwala pozmieniać dane
przed dodaniem do bazy
• json_prepare_post - może zastąpić własne end-
pointy
Moje dwa ulubione filtry:
• json_insert_post - pozwala pozmieniać dane
przed dodaniem do bazy
• json_prepare_post - może zastąpić własne end-
pointy
Moje dwa ulubione filtry:
• json_insert_post - pozwala pozmieniać dane
przed dodaniem do bazy
• json_prepare_post - może zastąpić własne end-
pointy
Pamiętajcie jednak, że…
v.1.* jako numer wersji JSON-API
jest zdecydowanie zawyżone ;-)
Szykuje się wersja 2.*
Szykuje się wersja 2.*
Niekompatybilna wstecz ;)

https://make.wordpress.org/core/2015/04/29/wp-rest-api-version-2-0-beta-1/
Szykuje się wersja 2.*
Dokumentacja: http://v2.wp-api.org/
Niekompatybilna wstecz ;)

https://make.wordpress.org/core/2015/04/29/wp-rest-api-version-2-0-beta-1/
Do odczytu świetne, do
zapisu niekoniecznie ;-)
Problemy z protected meta


Nie można ustawić _thumbnail_id
Problemy z protected meta


Nie można ustawić _thumbnail_id
Problemy z protected meta


Nie można ustawić _thumbnail_id
Pomaga:
add_filter('is_protected_meta', '__return_false');
Brak wsparcia dla
dodawania/edycji termsów
Brak wsparcia dla
dodawania/edycji termsów
Własne end-pointy na ratunek
Brak wsparcia dla definiowania
własnych taksonomii przy
tworzeniu wpisów
function wp_api_add_tax($post, $data, $update){
if(
!empty($data['custom_tax']) &&
is_array($data['custom_tax'])
) {
foreach( $data['custom_tax'] as $tax => $val ){
wp_set_post_terms( $post['ID'], $val, $tax );
}
}
}
add_action('json_insert_post', 'wp_api_add_tax', 10, 3);
I paru innych rzeczy…
http://wp-api.org/misc/comparison.html
Wydajność i cache
Porady jak przygotować WordPressa pod
wykorzystanie motywów SPA:
http://torquemag.io/preparing-wordpress-site-
power-single-page-web-app/
Wtyczka cache dla WP-API:
https://github.com/Shelob9/jp-rest-cache
Motyw jako SPA
Motyw-mapa
Motyw-mapa
Prawie jak samochód-chłodnia ;-)
Co wykorzystać?
REST API
Adresy URL, które wykorzystamy:
• wp-json/taxonomies/category/terms
• wp-json/posts?filter[posts_per_page]=200
• wp-json/posts?filter[posts_per_page]=200&filter[cat]=1,2,3
REST API
Adresy URL, które wykorzystamy:
• wp-json/taxonomies/category/terms
• wp-json/posts?filter[posts_per_page]=200
• wp-json/posts?filter[posts_per_page]=200&filter[cat]=1,2,3
REST API
Adresy URL, które wykorzystamy:
• wp-json/taxonomies/category/terms
• wp-json/posts?filter[posts_per_page]=200
• wp-json/posts?filter[posts_per_page]=200&filter[cat]=1,2,3
REST API
Adresy URL, które wykorzystamy:
• wp-json/taxonomies/category/terms
• wp-json/posts?filter[posts_per_page]=200
• wp-json/posts?filter[posts_per_page]=200&filter[cat]=1,2,3
Handlebars
http://handlebarsjs.com/
<script id="stats-popup-tmpl" type="text/x-handlebars-template">
<h3 class="stats__header"><?php _e('Znaleziono {{total}} odwiedzonych
miejsc', 'theme-map'); ?></h3>
<ul class="stats__list">
{{#each stats}}
<li class="stats__item">
<strong class="stats__counter{{#if count}} stats__counter--active{{/
if}}">{{count}}</strong> <img src="{{iconsUrl}}{{slug}}.svg" alt=""
class="stats__icon" /> {{name}}
</li>
{{/each}}
</ul>
</script>
Handlebars
http://handlebarsjs.com/
<script id="stats-popup-tmpl" type="text/x-handlebars-template">
<h3 class="stats__header"><?php _e('Znaleziono {{total}} odwiedzonych
miejsc', 'theme-map'); ?></h3>
<ul class="stats__list">
{{#each stats}}
<li class="stats__item">
<strong class="stats__counter{{#if count}} stats__counter--active{{/
if}}">{{count}}</strong> <img src="{{iconsUrl}}{{slug}}.svg" alt=""
class="stats__icon" /> {{name}}
</li>
{{/each}}
</ul>
</script>
Handlebars
http://handlebarsjs.com/
<script id="stats-popup-tmpl" type="text/x-handlebars-template">
<h3 class="stats__header"><?php _e('Znaleziono {{total}} odwiedzonych
miejsc', 'theme-map'); ?></h3>
<ul class="stats__list">
{{#each stats}}
<li class="stats__item">
<strong class="stats__counter{{#if count}} stats__counter--active{{/
if}}">{{count}}</strong> <img src="{{iconsUrl}}{{slug}}.svg" alt=""
class="stats__icon" /> {{name}}
</li>
{{/each}}
</ul>
</script>
Inne
Inne
• Google Maps API - bo musimy mieć jakieś mapy ;)

https://developers.google.com/maps/documentation/javascript/tutorial
• LocalStorage - do przechowywania filtrów
• History API - aby mieć dostęp poprzez URL do
konkretnych miejsc
• Snazzy maps

https://snazzymaps.com/
• Travel icon set

http://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/
Inne
• Google Maps API - bo musimy mieć jakieś mapy ;)

https://developers.google.com/maps/documentation/javascript/tutorial
• LocalStorage - do przechowywania filtrów
• History API - aby mieć dostęp poprzez URL do
konkretnych miejsc
• Snazzy maps

https://snazzymaps.com/
• Travel icon set

http://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/
Inne
• Google Maps API - bo musimy mieć jakieś mapy ;)

https://developers.google.com/maps/documentation/javascript/tutorial
• LocalStorage - do przechowywania filtrów
• History API - aby mieć dostęp poprzez URL do
konkretnych miejsc
• Snazzy maps

https://snazzymaps.com/
• Travel icon set

http://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/
Inne
• Google Maps API - bo musimy mieć jakieś mapy ;)

https://developers.google.com/maps/documentation/javascript/tutorial
• LocalStorage - do przechowywania filtrów
• History API - aby mieć dostęp poprzez URL do
konkretnych miejsc
• Snazzy maps

https://snazzymaps.com/
• Travel icon set

http://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/
Inne
• Google Maps API - bo musimy mieć jakieś mapy ;)

https://developers.google.com/maps/documentation/javascript/tutorial
• LocalStorage - do przechowywania filtrów
• History API - aby mieć dostęp poprzez URL do
konkretnych miejsc
• Snazzy maps

https://snazzymaps.com/
• Travel icon set

http://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/
Problemy?
Wprowadzanie pozycji
elementów na mapie
Wprowadzanie pozycji
elementów na mapie
Wtyczka Pronamic Google Maps

https://wordpress.org/plugins/pronamic-google-maps/
Wprowadzanie pozycji
elementów na mapie
Advanced Custom Fields

https://wordpress.org/plugins/advanced-custom-fields/
Wprowadzanie pozycji
elementów na mapie
Advanced Custom Fields

https://wordpress.org/plugins/advanced-custom-fields/
Warto pamiętać o zdefiniowaniu pól w motywie

http://www.advancedcustomfields.com/resources/local-json/
Brak publicznego dostępu
do post meta
Brak publicznego dostępu
do post meta
json_prepare_post rozwiąże ten problem
Duża liczba markerów
Duża liczba markerów
• Marker Clusterer

https://googlemaps.github.io/js-marker-clusterer/docs/examples.html
• Gorsze przypadki omówimy później ;)
Duża liczba markerów
• Marker Clusterer

https://googlemaps.github.io/js-marker-clusterer/docs/examples.html
• Gorsze przypadki omówimy później ;)
Wpis
Dane geolokalizacyjne
Kategoria
Kategoria
Tagi
Adres
Najważniejsze pliki motywu
• index.php - jedyny plik wyświetlający szablon
• index-templates.php - przechowuje szablony
Handlebars
• functions.php - konfiguracja wstępna i wczytywanie
plików JS/CSS
Najważniejsze pliki motywu
• index.php - jedyny plik wyświetlający szablon
• index-templates.php - przechowuje szablony
Handlebars
• functions.php - konfiguracja wstępna i wczytywanie
plików JS/CSS
Najważniejsze pliki motywu
• index.php - jedyny plik wyświetlający szablon
• index-templates.php - przechowuje szablony
Handlebars
• functions.php - konfiguracja wstępna i
wczytywanie plików JS/CSS
Najważniejsze pliki motywu
• index.php - jedyny plik wyświetlający szablon
• index-templates.php - przechowuje szablony
Handlebars
• functions.php - konfiguracja wstępna i
wczytywanie plików JS/CSS
• tgm.php - do ułatwienia/wymuszenia instalacji
potrzebnych wtyczek
Wczytywanie konfiguracji wstępnej
z ekranu personalizacji motywu
wp_register_script(
'tm-app',
get_template_directory_uri() . '/js/app.js',
array('jquery', ‘tm-handlebars’)
);
$app_config = array(
'URL' => home_url(),
'mapLatitude' => get_theme_mod('map_latitude', '51.919438'),
'mapLongitude' => get_theme_mod('map_longitude', '19.145135'),
'mapZoom' => get_theme_mod('map_zoom', '6'),
);
wp_localize_script( 'tm-app', 'appConfig', $app_config );
Wczytywanie konfiguracji wstępnej
z ekranu personalizacji motywu
wp_register_script(
'tm-app',
get_template_directory_uri() . '/js/app.js',
array('jquery', ‘tm-handlebars’)
);
$app_config = array(
'URL' => home_url(),
'mapLatitude' => get_theme_mod('map_latitude', '51.919438'),
'mapLongitude' => get_theme_mod('map_longitude', '19.145135'),
'mapZoom' => get_theme_mod('map_zoom', '6'),
);
wp_localize_script( 'tm-app', 'appConfig', $app_config );
Wczytywanie konfiguracji wstępnej
z ekranu personalizacji motywu
wp_register_script(
'tm-app',
get_template_directory_uri() . '/js/app.js',
array('jquery', ‘tm-handlebars’)
);
$app_config = array(
'URL' => home_url(),
'mapLatitude' => get_theme_mod('map_latitude', '51.919438'),
'mapLongitude' => get_theme_mod('map_longitude', '19.145135'),
'mapZoom' => get_theme_mod('map_zoom', '6'),
);
wp_localize_script( 'tm-app', 'appConfig', $app_config );
Pobieranie danych
$.ajax({
url: apiUrl + “posts?filter[posts_per_page]=200"
}).done(function( data ) {
// przetwarzanie danych
});
Pobieranie danych
$.ajax({
url: apiUrl + “posts?filter[posts_per_page]=200"
}).done(function( data ) {
// przetwarzanie danych
});
Pobieranie danych
$.ajax({
url: apiUrl + “posts?filter[posts_per_page]=200"
}).done(function( data ) {
// przetwarzanie danych
});
Pobieranie danych
$.ajax({
method: ‘GET’,
url: apiUrl + “posts?filter[posts_per_page]=200"
}).done(function( data ) {
// przetwarzanie danych
});
Pobieranie danych
$.ajax({
method: ‘GET’,
cache: false,
url: apiUrl + “posts?filter[posts_per_page]=200"
}).done(function( data ) {
// przetwarzanie danych
});
Wyświetlanie popupu
Dodawanie danych geograficznych do posta
if( ! function_exists( 'tm_geodata' ) ) :
function tm_geodata($data, $post, $context) {
$data['geodata'] = array(
'latitude' => get_post_meta(
$post['ID'], '_pronamic_google_maps_latitude', true ),
'longitude' => get_post_meta(
$post['ID'], '_pronamic_google_maps_longitude', true ),
'address' => get_post_meta(
$post['ID'], '_pronamic_google_maps_address', true )
);
return $data;
}
endif; // tm_geodata
add_filter( 'json_prepare_post', 'tm_geodata', 10, 3 );
Wyświetlanie popupu
Dodawanie danych geograficznych do posta
if( ! function_exists( 'tm_geodata' ) ) :
function tm_geodata($data, $post, $context) {
$data['geodata'] = array(
'latitude' => get_post_meta(
$post['ID'], '_pronamic_google_maps_latitude', true ),
'longitude' => get_post_meta(
$post['ID'], '_pronamic_google_maps_longitude', true ),
'address' => get_post_meta(
$post['ID'], '_pronamic_google_maps_address', true )
);
return $data;
}
endif; // tm_geodata
add_filter( 'json_prepare_post', 'tm_geodata', 10, 3 );
Wyświetlanie popupu
Dodawanie danych geograficznych do posta
if( ! function_exists( 'tm_geodata' ) ) :
function tm_geodata($data, $post, $context) {
$data['geodata'] = array(
'latitude' => get_post_meta(
$post['ID'], '_pronamic_google_maps_latitude', true ),
'longitude' => get_post_meta(
$post['ID'], '_pronamic_google_maps_longitude', true ),
'address' => get_post_meta(
$post['ID'], '_pronamic_google_maps_address', true )
);
return $data;
}
endif; // tm_geodata
add_filter( 'json_prepare_post', 'tm_geodata', 10, 3 );
Wyświetlanie popupu
Dodawanie danych geograficznych do posta
if( ! function_exists( 'tm_geodata' ) ) :
function tm_geodata($data, $post, $context) {
$data['geodata'] = array(
'latitude' => get_post_meta(
$post['ID'], '_pronamic_google_maps_latitude', true ),
'longitude' => get_post_meta(
$post['ID'], '_pronamic_google_maps_longitude', true ),
'address' => get_post_meta(
$post['ID'], '_pronamic_google_maps_address', true )
);
return $data;
}
endif; // tm_geodata
add_filter( 'json_prepare_post', 'tm_geodata', 10, 3 );
Wyświetlanie popupu
showPopup: function(data) {
$('.popup__wrap--data').html(templatePopup({
"title": data.title,
"address": data.geodata.address,
"body": data.content,
"rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) :
null,
"image": data.featured_image ? data.featured_image.source : null,
"categorySlug": data.terms.category[0].slug
}));
uiPopup.show('--data');
history.pushState(null, null, baseUrl + data.slug);
},
Wyświetlanie popupu
showPopup: function(data) {
$('.popup__wrap--data').html(templatePopup({
"title": data.title,
"address": data.geodata.address,
"body": data.content,
"rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) :
null,
"image": data.featured_image ? data.featured_image.source : null,
"categorySlug": data.terms.category[0].slug
}));
uiPopup.show('--data');
history.pushState(null, null, baseUrl + data.slug);
},
Wyświetlanie popupu
showPopup: function(data) {
$('.popup__wrap--data').html(templatePopup({
"title": data.title,
"address": data.geodata.address,
"body": data.content,
"rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) :
null,
"image": data.featured_image ? data.featured_image.source : null,
"categorySlug": data.terms.category[0].slug
}));
uiPopup.show('--data');
history.pushState(null, null, baseUrl + data.slug);
},
Wyświetlanie popupu
showPopup: function(data) {
$('.popup__wrap--data').html(templatePopup({
"title": data.title,
"address": data.geodata.address,
"body": data.content,
"rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) :
null,
"image": data.featured_image ? data.featured_image.source : null,
"categorySlug": data.terms.category[0].slug
}));
uiPopup.show('--data');
history.pushState(null, null, baseUrl + data.slug);
},
Wyświetlanie popupu
showPopup: function(data) {
$('.popup__wrap--data').html(templatePopup({
"title": data.title,
"address": data.geodata.address,
"body": data.content,
"rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) :
null,
"image": data.featured_image ? data.featured_image.source : null,
"categorySlug": data.terms.category[0].slug
}));
uiPopup.show('--data');
history.pushState(null, null, baseUrl + data.slug);
},
Wyświetlanie popupu
showPopup: function(data) {
$('.popup__wrap--data').html(templatePopup({
"title": data.title,
"address": data.geodata.address,
"body": data.content,
"rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) :
null,
"image": data.featured_image ? data.featured_image.source : null,
"categorySlug": data.terms.category[0].slug
}));
uiPopup.show('--data');
history.pushState(null, null, baseUrl + data.slug);
},
Wyświetlanie popupu
showPopup: function(data) {
$('.popup__wrap--data').html(templatePopup({
"title": data.title,
"address": data.geodata.address,
"body": data.content,
"rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) :
null,
"image": data.featured_image ? data.featured_image.source : null,
"categorySlug": data.terms.category[0].slug
}));
uiPopup.show('--data');
history.pushState(null, null, baseUrl + data.slug);
},
Wyświetlanie popupu
showPopup: function(data) {
$('.popup__wrap--data').html(templatePopup({
"title": data.title,
"address": data.geodata.address,
"body": data.content,
"rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) :
null,
"image": data.featured_image ? data.featured_image.source : null,
"categorySlug": data.terms.category[0].slug
}));
uiPopup.show('--data');
history.pushState(null, null, baseUrl + data.slug);
},
Wyświetlanie popupu
showPopup: function(data) {
$('.popup__wrap--data').html(templatePopup({
"title": data.title,
"address": data.geodata.address,
"body": data.content,
"rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) :
null,
"image": data.featured_image ? data.featured_image.source : null,
"categorySlug": data.terms.category[0].slug
}));
uiPopup.show('--data');
history.pushState(null, null, baseUrl + data.slug);
},
Wyświetlanie popupu
showPopup: function(data) {
$('.popup__wrap--data').html(templatePopup({
"title": data.title,
"address": data.geodata.address,
"body": data.content,
"rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) :
null,
"image": data.featured_image ? data.featured_image.source : null,
"categorySlug": data.terms.category[0].slug
}));
uiPopup.show('--data');
history.pushState(null, null, baseUrl + data.slug);
},
Co dalej?
1 wpis = 2-5kB
100 wpisów = ~200-500kB
1 wpis = 2-5kB
100 wpisów = ~200-500kB
Dla większej liczby
markerów
• Utworzenie własnych end-pointów do serwowania
danych markerów:
• ID,
• Dane geolokalizacyjne
• Kategoria
• Reszta danych wczytywana po kliknięciu popupa
poprzez wp-json/posts/<id>
Dla większej liczby
markerów
• Utworzenie własnych end-pointów do serwowania
danych markerów:
• ID,
• Dane geolokalizacyjne
• Kategoria
• Reszta danych wczytywana po kliknięciu popupa
poprzez wp-json/posts/<id>
Dla większej liczby
markerów
• Utworzenie własnych end-pointów do serwowania
danych markerów:
• ID,
• Dane geolokalizacyjne
• Kategoria
• Reszta danych wczytywana po kliknięciu popupa
poprzez wp-json/posts/<id>
Gdy mamy bardzo dużo
markerów
• Wczytywanie markerów zależnie od widocznego
obszaru mapy
• Przygotowanie end-pointu, który na bazie zakresu
szerokości i długości geograficznej zwróci listę
markerów na danym obszarze
Gdy mamy bardzo dużo
markerów
• Wczytywanie markerów zależnie od widocznego
obszaru mapy
• Przygotowanie end-pointu, który na bazie zakresu
szerokości i długości geograficznej zwróci listę
markerów na danym obszarze
Dlaczego
Dziudek ❤ WP-API ?
• Znam dobrze WordPressowy kokpit…
• … umiem go modyfikować do swoich potrzeb …
• … i zaoszczędzić sobie sporo czasu poprzez
wykorzystanie gotowych wtyczek …
• … dzięki WP-API mogę ten kokpit połączyć na
front-endzie z czymkolwiek zechcę :-)
• Znam dobrze WordPressowy kokpit…
• … umiem go dostosować do swoich potrzeb …
• … i zaoszczędzić sobie sporo czasu poprzez
wykorzystanie gotowych wtyczek …
• … dzięki WP-API mogę ten kokpit połączyć na
front-endzie z czymkolwiek zechcę :-)
• Znam dobrze WordPressowy kokpit…
• … umiem go dostosować do swoich potrzeb …
• … i zaoszczędzić sobie sporo czasu poprzez
wykorzystanie gotowych wtyczek …
• … dzięki WP-API mogę ten kokpit połączyć na
front-endzie z czymkolwiek zechcę :-)
• Znam dobrze WordPressowy kokpit…
• … umiem go dostosować do swoich potrzeb …
• … i zaoszczędzić sobie sporo czasu poprzez
wykorzystanie gotowych wtyczek …
• … dzięki WP-API mogę ten kokpit połączyć na
front-endzie z czymkolwiek zechcę :-)
Kod przykładu:
https://github.com/dziudek/theme-map
DEMO
Lektura
• Wykorzystanie taksonomii w WP-API

http://torquemag.io/working-taxonomies-using-json-rest-api/
• Tworzenie widżetów z użyciem WP-API

http://webdevstudios.com/2015/03/26/how-to-create-an-auto-updating-widget-using-wp-api/
• Postęp łączenia WP-API z WordPressem

https://github.com/WP-API/WP-API/issues/571
Tomasz Dziuda
Lead Developer @
@dziudek
http://dziudek.pl
dziudek@gavick.com
Pytania?

WP-API - teoria i praktyka - WordUp Łódź #4

  • 1.
    WP-API teoria i praktyka TomaszDziuda WordUp Łódź #4 10.VI.2015
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
    Przykłady • wp-json/posts/303 • wp-json/posts?filter[cat]=1,2,3 •wp-json/posts?filter[posts_per_page]=20 • Więcej filtrów: http://wp-api.org/#posts_retrieve-posts • wp-json/taxonomies/category/terms • wp-json/users/me
  • 12.
    Przykłady • wp-json/posts/303 • wp-json/posts?filter[cat]=1,2,3 •wp-json/posts?filter[posts_per_page]=20 • Więcej filtrów: http://wp-api.org/#posts_retrieve-posts • wp-json/taxonomies/category/terms • wp-json/users/me
  • 13.
    Przykłady • wp-json/posts/303 • wp-json/posts?filter[cat]=1,2,3 •wp-json/posts?filter[posts_per_page]=20 • Więcej filtrów: http://wp-api.org/#posts_retrieve-posts • wp-json/taxonomies/category/terms • wp-json/users/me
  • 14.
    Przykłady • wp-json/posts/303 • wp-json/posts?filter[cat]=1,2,3 •wp-json/posts?filter[posts_per_page]=20 • Więcej filtrów: http://wp-api.org/#posts_retrieve-posts • wp-json/taxonomies/category/terms • wp-json/users/me
  • 15.
    Przykłady • wp-json/posts/303 • wp-json/posts?filter[cat]=1,2,3 •wp-json/posts?filter[posts_per_page]=20 • Więcej filtrów: http://wp-api.org/#posts_retrieve-posts • wp-json/taxonomies/category/terms • wp-json/users/me
  • 16.
    Przykłady • wp-json/posts/303 • wp-json/posts?filter[cat]=1,2,3 •wp-json/posts?filter[posts_per_page]=20 • Więcej filtrów: http://wp-api.org/#posts_retrieve-posts • wp-json/taxonomies/category/terms • wp-json/users/me
  • 17.
    GET / HEAD- odczyt istniejącego elementu POST - tworzenie nowego elementu PUT / PATCH - edycja elementu DELETE - usunięcie elementu
  • 18.
    GET / HEAD- odczyt istniejącego elementu POST - tworzenie nowego elementu PUT / PATCH - edycja elementu DELETE - usunięcie elementu
  • 19.
    GET / HEAD- odczyt istniejącego elementu POST - tworzenie nowego elementu PUT / PATCH - edycja elementu DELETE - usunięcie elementu
  • 20.
    GET / HEAD- odczyt istniejącego elementu POST - tworzenie nowego elementu PUT / PATCH - edycja elementu DELETE - usunięcie elementu
  • 21.
    GET / HEAD- odczyt istniejącego elementu POST - tworzenie nowego elementu PUT / PATCH - edycja elementu DELETE - usunięcie elementu Wymagają zawsze autoryzacji Wymagają CZASAMI autoryzacji
  • 22.
  • 23.
    JSON jako nośnikdanych • Zajmuje mniej miejsca niż XML • Można go łatwiej przetwarzać z użyciem JavaScript • http://www.json.org/xml.html
  • 24.
    JSON jako nośnikdanych • Zajmuje mniej miejsca niż XML • Można go łatwiej przetwarzać z użyciem JavaScript • http://www.json.org/xml.html
  • 25.
    JSON jako nośnikdanych • Zajmuje mniej miejsca niż XML • Można go łatwiej przetwarzać z użyciem JavaScript • http://www.json.org/xml.html
  • 27.
    Wtyczka JSON Viewer:https://chrome.google.com/webstore/detail/json-viewer/ gbmdgpbipfallnflgajpaliibnhdgobh/
  • 28.
    Akcje wymagające autoryzacji • Tworzeniei modyfikacja postów • Odczyt rewizji postów • Tworzenie załączników • Tworzenie, modyfikacja, odczyt post meta • Tworzenie, modyfikacja, odczyt użytkowników
  • 29.
  • 30.
    Cookie Auth • Standardowametoda autoryzacji dla wtyczek i motywów • Wymaga przesłania w zapytaniu AJAX-owym dodatkowego nagłówka X-WP-Nonce
 http://wp-api.org/guides/authentication.html#cookie-authentication
  • 31.
    Cookie Auth • Standardowametoda autoryzacji dla wtyczek i motywów • Wymaga przesłania w zapytaniu AJAX-owym dodatkowego nagłówka X-WP-Nonce
 http://wp-api.org/guides/authentication.html#cookie-authentication
  • 32.
    OAuth • Dla aplikacjizewnętrznych - webowych, mobilnych, desktopowych • Wymaga dodatkowego pluginu - OAuth Server
 https://github.com/WP-API/OAuth1 • Wsparcie tylko dla OAuth 1.* • Niestety obecnie nie ma UI do zarządzania kluczami
  • 33.
    OAuth • Dla aplikacjizewnętrznych - webowych, mobilnych, desktopowych • Wymaga dodatkowego pluginu - OAuth Server
 https://github.com/WP-API/OAuth1 • Wsparcie tylko dla OAuth 1.* • Niestety obecnie nie ma UI do zarządzania kluczami
  • 34.
    OAuth • Dla aplikacjizewnętrznych - webowych, mobilnych, desktopowych • Wymaga dodatkowego pluginu - OAuth Server
 https://github.com/WP-API/OAuth1 • Wsparcie tylko dla OAuth 1.* • Niestety obecnie nie ma UI do zarządzania kluczami
  • 35.
    OAuth • Dla aplikacjizewnętrznych - webowych, mobilnych, desktopowych • Wymaga dodatkowego pluginu - OAuth Server
 https://github.com/WP-API/OAuth1 • Wsparcie tylko dla OAuth 1.* • Niestety obecnie nie ma UI do zarządzania kluczami
  • 36.
    Basic Auth • Tylkodo środowisk testowych, istnieje duże ryzyko wycieku hasła wskutek braku szyfrowania • Wymaga dodatkowej wtyczki: Basic Auth
 https://github.com/WP-API/Basic-Auth
  • 37.
    Basic Auth • Tylkodo środowisk testowych, istnieje duże ryzyko wycieku hasła wskutek braku szyfrowania • Wymaga dodatkowej wtyczki: Basic Auth
 https://github.com/WP-API/Basic-Auth
  • 38.
    Własne metody • Wymagająimplementacji z użyciem filtra json_authentication_errors
 https://apppresser.com/custom-wp-api-authentication/ • Można zaimplementować np. JSON Web Tokens
 http://jwt.io/
  • 39.
    Własne metody • Wymagająimplementacji z użyciem filtra json_authentication_errors
 https://apppresser.com/custom-wp-api-authentication/ • Można zaimplementować np. JSON Web Tokens
 http://jwt.io/
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
    Kalendarz WordUpów • PrzygotowujemyWordPressa z listą WordUpów • Tworzymy odpowiednie custom fields opisujące WordUpy • Tworzymy widżet, który pobiera te informacje • Wykorzystujemy HTTP API albo JSON-P
 
 https://codex.wordpress.org/HTTP_API
 http://json-p.org/

  • 60.
    Kalendarz WordUpów • PrzygotowujemyWordPressa z listą WordUpów • Tworzymy odpowiednie custom fields opisujące WordUpy • Tworzymy widżet, który pobiera te informacje • Wykorzystujemy HTTP API albo JSON-P
 
 https://codex.wordpress.org/HTTP_API
 http://json-p.org/

  • 61.
    Kalendarz WordUpów • PrzygotowujemyWordPressa z listą WordUpów • Tworzymy odpowiednie custom fields opisujące WordUpy • Tworzymy widżet, który pobiera te informacje • Wykorzystujemy HTTP API albo JSON-P
 
 https://codex.wordpress.org/HTTP_API
 http://json-p.org/

  • 62.
    Kalendarz WordUpów • PrzygotowujemyWordPressa z listą WordUpów • Tworzymy odpowiednie custom fields opisujące WordUpy • Tworzymy widżet, który pobiera te informacje • Wykorzystujemy HTTP API albo JSON-P
 
 https://codex.wordpress.org/HTTP_API
 http://json-p.org/

  • 63.
  • 64.
  • 65.
    Moje dwa ulubionefiltry: • json_insert_post - pozwala pozmieniać dane przed dodaniem do bazy • json_prepare_post - może zastąpić własne end- pointy
  • 66.
    Moje dwa ulubionefiltry: • json_insert_post - pozwala pozmieniać dane przed dodaniem do bazy • json_prepare_post - może zastąpić własne end- pointy
  • 67.
    Moje dwa ulubionefiltry: • json_insert_post - pozwala pozmieniać dane przed dodaniem do bazy • json_prepare_post - może zastąpić własne end- pointy
  • 68.
  • 69.
    v.1.* jako numerwersji JSON-API jest zdecydowanie zawyżone ;-)
  • 70.
  • 71.
    Szykuje się wersja2.* Niekompatybilna wstecz ;)
 https://make.wordpress.org/core/2015/04/29/wp-rest-api-version-2-0-beta-1/
  • 72.
    Szykuje się wersja2.* Dokumentacja: http://v2.wp-api.org/ Niekompatybilna wstecz ;)
 https://make.wordpress.org/core/2015/04/29/wp-rest-api-version-2-0-beta-1/
  • 73.
    Do odczytu świetne,do zapisu niekoniecznie ;-)
  • 74.
    Problemy z protectedmeta 
 Nie można ustawić _thumbnail_id
  • 75.
    Problemy z protectedmeta 
 Nie można ustawić _thumbnail_id
  • 76.
    Problemy z protectedmeta 
 Nie można ustawić _thumbnail_id Pomaga: add_filter('is_protected_meta', '__return_false');
  • 77.
  • 78.
    Brak wsparcia dla dodawania/edycjitermsów Własne end-pointy na ratunek
  • 79.
    Brak wsparcia dladefiniowania własnych taksonomii przy tworzeniu wpisów
  • 80.
    function wp_api_add_tax($post, $data,$update){ if( !empty($data['custom_tax']) && is_array($data['custom_tax']) ) { foreach( $data['custom_tax'] as $tax => $val ){ wp_set_post_terms( $post['ID'], $val, $tax ); } } } add_action('json_insert_post', 'wp_api_add_tax', 10, 3);
  • 81.
    I paru innychrzeczy… http://wp-api.org/misc/comparison.html
  • 82.
  • 83.
    Porady jak przygotowaćWordPressa pod wykorzystanie motywów SPA: http://torquemag.io/preparing-wordpress-site- power-single-page-web-app/ Wtyczka cache dla WP-API: https://github.com/Shelob9/jp-rest-cache
  • 84.
  • 85.
  • 86.
  • 90.
  • 91.
    REST API Adresy URL,które wykorzystamy: • wp-json/taxonomies/category/terms • wp-json/posts?filter[posts_per_page]=200 • wp-json/posts?filter[posts_per_page]=200&filter[cat]=1,2,3
  • 92.
    REST API Adresy URL,które wykorzystamy: • wp-json/taxonomies/category/terms • wp-json/posts?filter[posts_per_page]=200 • wp-json/posts?filter[posts_per_page]=200&filter[cat]=1,2,3
  • 93.
    REST API Adresy URL,które wykorzystamy: • wp-json/taxonomies/category/terms • wp-json/posts?filter[posts_per_page]=200 • wp-json/posts?filter[posts_per_page]=200&filter[cat]=1,2,3
  • 94.
    REST API Adresy URL,które wykorzystamy: • wp-json/taxonomies/category/terms • wp-json/posts?filter[posts_per_page]=200 • wp-json/posts?filter[posts_per_page]=200&filter[cat]=1,2,3
  • 95.
    Handlebars http://handlebarsjs.com/ <script id="stats-popup-tmpl" type="text/x-handlebars-template"> <h3class="stats__header"><?php _e('Znaleziono {{total}} odwiedzonych miejsc', 'theme-map'); ?></h3> <ul class="stats__list"> {{#each stats}} <li class="stats__item"> <strong class="stats__counter{{#if count}} stats__counter--active{{/ if}}">{{count}}</strong> <img src="{{iconsUrl}}{{slug}}.svg" alt="" class="stats__icon" /> {{name}} </li> {{/each}} </ul> </script>
  • 96.
    Handlebars http://handlebarsjs.com/ <script id="stats-popup-tmpl" type="text/x-handlebars-template"> <h3class="stats__header"><?php _e('Znaleziono {{total}} odwiedzonych miejsc', 'theme-map'); ?></h3> <ul class="stats__list"> {{#each stats}} <li class="stats__item"> <strong class="stats__counter{{#if count}} stats__counter--active{{/ if}}">{{count}}</strong> <img src="{{iconsUrl}}{{slug}}.svg" alt="" class="stats__icon" /> {{name}} </li> {{/each}} </ul> </script>
  • 97.
    Handlebars http://handlebarsjs.com/ <script id="stats-popup-tmpl" type="text/x-handlebars-template"> <h3class="stats__header"><?php _e('Znaleziono {{total}} odwiedzonych miejsc', 'theme-map'); ?></h3> <ul class="stats__list"> {{#each stats}} <li class="stats__item"> <strong class="stats__counter{{#if count}} stats__counter--active{{/ if}}">{{count}}</strong> <img src="{{iconsUrl}}{{slug}}.svg" alt="" class="stats__icon" /> {{name}} </li> {{/each}} </ul> </script>
  • 98.
  • 99.
    Inne • Google MapsAPI - bo musimy mieć jakieś mapy ;)
 https://developers.google.com/maps/documentation/javascript/tutorial • LocalStorage - do przechowywania filtrów • History API - aby mieć dostęp poprzez URL do konkretnych miejsc • Snazzy maps
 https://snazzymaps.com/ • Travel icon set
 http://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/
  • 100.
    Inne • Google MapsAPI - bo musimy mieć jakieś mapy ;)
 https://developers.google.com/maps/documentation/javascript/tutorial • LocalStorage - do przechowywania filtrów • History API - aby mieć dostęp poprzez URL do konkretnych miejsc • Snazzy maps
 https://snazzymaps.com/ • Travel icon set
 http://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/
  • 101.
    Inne • Google MapsAPI - bo musimy mieć jakieś mapy ;)
 https://developers.google.com/maps/documentation/javascript/tutorial • LocalStorage - do przechowywania filtrów • History API - aby mieć dostęp poprzez URL do konkretnych miejsc • Snazzy maps
 https://snazzymaps.com/ • Travel icon set
 http://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/
  • 102.
    Inne • Google MapsAPI - bo musimy mieć jakieś mapy ;)
 https://developers.google.com/maps/documentation/javascript/tutorial • LocalStorage - do przechowywania filtrów • History API - aby mieć dostęp poprzez URL do konkretnych miejsc • Snazzy maps
 https://snazzymaps.com/ • Travel icon set
 http://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/
  • 103.
    Inne • Google MapsAPI - bo musimy mieć jakieś mapy ;)
 https://developers.google.com/maps/documentation/javascript/tutorial • LocalStorage - do przechowywania filtrów • History API - aby mieć dostęp poprzez URL do konkretnych miejsc • Snazzy maps
 https://snazzymaps.com/ • Travel icon set
 http://www.smashingmagazine.com/2014/12/23/freebie-tourism-travel-icon-set-100-icons-png-svg/
  • 104.
  • 105.
  • 106.
    Wprowadzanie pozycji elementów namapie Wtyczka Pronamic Google Maps
 https://wordpress.org/plugins/pronamic-google-maps/
  • 107.
    Wprowadzanie pozycji elementów namapie Advanced Custom Fields
 https://wordpress.org/plugins/advanced-custom-fields/
  • 108.
    Wprowadzanie pozycji elementów namapie Advanced Custom Fields
 https://wordpress.org/plugins/advanced-custom-fields/ Warto pamiętać o zdefiniowaniu pól w motywie
 http://www.advancedcustomfields.com/resources/local-json/
  • 109.
  • 110.
    Brak publicznego dostępu dopost meta json_prepare_post rozwiąże ten problem
  • 111.
  • 112.
    Duża liczba markerów •Marker Clusterer
 https://googlemaps.github.io/js-marker-clusterer/docs/examples.html • Gorsze przypadki omówimy później ;)
  • 113.
    Duża liczba markerów •Marker Clusterer
 https://googlemaps.github.io/js-marker-clusterer/docs/examples.html • Gorsze przypadki omówimy później ;)
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
    Najważniejsze pliki motywu •index.php - jedyny plik wyświetlający szablon • index-templates.php - przechowuje szablony Handlebars • functions.php - konfiguracja wstępna i wczytywanie plików JS/CSS
  • 121.
    Najważniejsze pliki motywu •index.php - jedyny plik wyświetlający szablon • index-templates.php - przechowuje szablony Handlebars • functions.php - konfiguracja wstępna i wczytywanie plików JS/CSS
  • 122.
    Najważniejsze pliki motywu •index.php - jedyny plik wyświetlający szablon • index-templates.php - przechowuje szablony Handlebars • functions.php - konfiguracja wstępna i wczytywanie plików JS/CSS
  • 123.
    Najważniejsze pliki motywu •index.php - jedyny plik wyświetlający szablon • index-templates.php - przechowuje szablony Handlebars • functions.php - konfiguracja wstępna i wczytywanie plików JS/CSS • tgm.php - do ułatwienia/wymuszenia instalacji potrzebnych wtyczek
  • 124.
    Wczytywanie konfiguracji wstępnej zekranu personalizacji motywu wp_register_script( 'tm-app', get_template_directory_uri() . '/js/app.js', array('jquery', ‘tm-handlebars’) ); $app_config = array( 'URL' => home_url(), 'mapLatitude' => get_theme_mod('map_latitude', '51.919438'), 'mapLongitude' => get_theme_mod('map_longitude', '19.145135'), 'mapZoom' => get_theme_mod('map_zoom', '6'), ); wp_localize_script( 'tm-app', 'appConfig', $app_config );
  • 125.
    Wczytywanie konfiguracji wstępnej zekranu personalizacji motywu wp_register_script( 'tm-app', get_template_directory_uri() . '/js/app.js', array('jquery', ‘tm-handlebars’) ); $app_config = array( 'URL' => home_url(), 'mapLatitude' => get_theme_mod('map_latitude', '51.919438'), 'mapLongitude' => get_theme_mod('map_longitude', '19.145135'), 'mapZoom' => get_theme_mod('map_zoom', '6'), ); wp_localize_script( 'tm-app', 'appConfig', $app_config );
  • 126.
    Wczytywanie konfiguracji wstępnej zekranu personalizacji motywu wp_register_script( 'tm-app', get_template_directory_uri() . '/js/app.js', array('jquery', ‘tm-handlebars’) ); $app_config = array( 'URL' => home_url(), 'mapLatitude' => get_theme_mod('map_latitude', '51.919438'), 'mapLongitude' => get_theme_mod('map_longitude', '19.145135'), 'mapZoom' => get_theme_mod('map_zoom', '6'), ); wp_localize_script( 'tm-app', 'appConfig', $app_config );
  • 127.
    Pobieranie danych $.ajax({ url: apiUrl+ “posts?filter[posts_per_page]=200" }).done(function( data ) { // przetwarzanie danych });
  • 128.
    Pobieranie danych $.ajax({ url: apiUrl+ “posts?filter[posts_per_page]=200" }).done(function( data ) { // przetwarzanie danych });
  • 129.
    Pobieranie danych $.ajax({ url: apiUrl+ “posts?filter[posts_per_page]=200" }).done(function( data ) { // przetwarzanie danych });
  • 130.
    Pobieranie danych $.ajax({ method: ‘GET’, url:apiUrl + “posts?filter[posts_per_page]=200" }).done(function( data ) { // przetwarzanie danych });
  • 131.
    Pobieranie danych $.ajax({ method: ‘GET’, cache:false, url: apiUrl + “posts?filter[posts_per_page]=200" }).done(function( data ) { // przetwarzanie danych });
  • 132.
    Wyświetlanie popupu Dodawanie danychgeograficznych do posta if( ! function_exists( 'tm_geodata' ) ) : function tm_geodata($data, $post, $context) { $data['geodata'] = array( 'latitude' => get_post_meta( $post['ID'], '_pronamic_google_maps_latitude', true ), 'longitude' => get_post_meta( $post['ID'], '_pronamic_google_maps_longitude', true ), 'address' => get_post_meta( $post['ID'], '_pronamic_google_maps_address', true ) ); return $data; } endif; // tm_geodata add_filter( 'json_prepare_post', 'tm_geodata', 10, 3 );
  • 133.
    Wyświetlanie popupu Dodawanie danychgeograficznych do posta if( ! function_exists( 'tm_geodata' ) ) : function tm_geodata($data, $post, $context) { $data['geodata'] = array( 'latitude' => get_post_meta( $post['ID'], '_pronamic_google_maps_latitude', true ), 'longitude' => get_post_meta( $post['ID'], '_pronamic_google_maps_longitude', true ), 'address' => get_post_meta( $post['ID'], '_pronamic_google_maps_address', true ) ); return $data; } endif; // tm_geodata add_filter( 'json_prepare_post', 'tm_geodata', 10, 3 );
  • 134.
    Wyświetlanie popupu Dodawanie danychgeograficznych do posta if( ! function_exists( 'tm_geodata' ) ) : function tm_geodata($data, $post, $context) { $data['geodata'] = array( 'latitude' => get_post_meta( $post['ID'], '_pronamic_google_maps_latitude', true ), 'longitude' => get_post_meta( $post['ID'], '_pronamic_google_maps_longitude', true ), 'address' => get_post_meta( $post['ID'], '_pronamic_google_maps_address', true ) ); return $data; } endif; // tm_geodata add_filter( 'json_prepare_post', 'tm_geodata', 10, 3 );
  • 135.
    Wyświetlanie popupu Dodawanie danychgeograficznych do posta if( ! function_exists( 'tm_geodata' ) ) : function tm_geodata($data, $post, $context) { $data['geodata'] = array( 'latitude' => get_post_meta( $post['ID'], '_pronamic_google_maps_latitude', true ), 'longitude' => get_post_meta( $post['ID'], '_pronamic_google_maps_longitude', true ), 'address' => get_post_meta( $post['ID'], '_pronamic_google_maps_address', true ) ); return $data; } endif; // tm_geodata add_filter( 'json_prepare_post', 'tm_geodata', 10, 3 );
  • 136.
    Wyświetlanie popupu showPopup: function(data){ $('.popup__wrap--data').html(templatePopup({ "title": data.title, "address": data.geodata.address, "body": data.content, "rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) : null, "image": data.featured_image ? data.featured_image.source : null, "categorySlug": data.terms.category[0].slug })); uiPopup.show('--data'); history.pushState(null, null, baseUrl + data.slug); },
  • 137.
    Wyświetlanie popupu showPopup: function(data){ $('.popup__wrap--data').html(templatePopup({ "title": data.title, "address": data.geodata.address, "body": data.content, "rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) : null, "image": data.featured_image ? data.featured_image.source : null, "categorySlug": data.terms.category[0].slug })); uiPopup.show('--data'); history.pushState(null, null, baseUrl + data.slug); },
  • 138.
    Wyświetlanie popupu showPopup: function(data){ $('.popup__wrap--data').html(templatePopup({ "title": data.title, "address": data.geodata.address, "body": data.content, "rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) : null, "image": data.featured_image ? data.featured_image.source : null, "categorySlug": data.terms.category[0].slug })); uiPopup.show('--data'); history.pushState(null, null, baseUrl + data.slug); },
  • 139.
    Wyświetlanie popupu showPopup: function(data){ $('.popup__wrap--data').html(templatePopup({ "title": data.title, "address": data.geodata.address, "body": data.content, "rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) : null, "image": data.featured_image ? data.featured_image.source : null, "categorySlug": data.terms.category[0].slug })); uiPopup.show('--data'); history.pushState(null, null, baseUrl + data.slug); },
  • 140.
    Wyświetlanie popupu showPopup: function(data){ $('.popup__wrap--data').html(templatePopup({ "title": data.title, "address": data.geodata.address, "body": data.content, "rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) : null, "image": data.featured_image ? data.featured_image.source : null, "categorySlug": data.terms.category[0].slug })); uiPopup.show('--data'); history.pushState(null, null, baseUrl + data.slug); },
  • 141.
    Wyświetlanie popupu showPopup: function(data){ $('.popup__wrap--data').html(templatePopup({ "title": data.title, "address": data.geodata.address, "body": data.content, "rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) : null, "image": data.featured_image ? data.featured_image.source : null, "categorySlug": data.terms.category[0].slug })); uiPopup.show('--data'); history.pushState(null, null, baseUrl + data.slug); },
  • 142.
    Wyświetlanie popupu showPopup: function(data){ $('.popup__wrap--data').html(templatePopup({ "title": data.title, "address": data.geodata.address, "body": data.content, "rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) : null, "image": data.featured_image ? data.featured_image.source : null, "categorySlug": data.terms.category[0].slug })); uiPopup.show('--data'); history.pushState(null, null, baseUrl + data.slug); },
  • 143.
    Wyświetlanie popupu showPopup: function(data){ $('.popup__wrap--data').html(templatePopup({ "title": data.title, "address": data.geodata.address, "body": data.content, "rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) : null, "image": data.featured_image ? data.featured_image.source : null, "categorySlug": data.terms.category[0].slug })); uiPopup.show('--data'); history.pushState(null, null, baseUrl + data.slug); },
  • 144.
    Wyświetlanie popupu showPopup: function(data){ $('.popup__wrap--data').html(templatePopup({ "title": data.title, "address": data.geodata.address, "body": data.content, "rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) : null, "image": data.featured_image ? data.featured_image.source : null, "categorySlug": data.terms.category[0].slug })); uiPopup.show('--data'); history.pushState(null, null, baseUrl + data.slug); },
  • 145.
    Wyświetlanie popupu showPopup: function(data){ $('.popup__wrap--data').html(templatePopup({ "title": data.title, "address": data.geodata.address, "body": data.content, "rating": data.terms.post_tag ? parseInt(data.terms.post_tag[0].slug, 10) : null, "image": data.featured_image ? data.featured_image.source : null, "categorySlug": data.terms.category[0].slug })); uiPopup.show('--data'); history.pushState(null, null, baseUrl + data.slug); },
  • 146.
  • 147.
    1 wpis =2-5kB 100 wpisów = ~200-500kB
  • 148.
    1 wpis =2-5kB 100 wpisów = ~200-500kB
  • 149.
    Dla większej liczby markerów •Utworzenie własnych end-pointów do serwowania danych markerów: • ID, • Dane geolokalizacyjne • Kategoria • Reszta danych wczytywana po kliknięciu popupa poprzez wp-json/posts/<id>
  • 150.
    Dla większej liczby markerów •Utworzenie własnych end-pointów do serwowania danych markerów: • ID, • Dane geolokalizacyjne • Kategoria • Reszta danych wczytywana po kliknięciu popupa poprzez wp-json/posts/<id>
  • 151.
    Dla większej liczby markerów •Utworzenie własnych end-pointów do serwowania danych markerów: • ID, • Dane geolokalizacyjne • Kategoria • Reszta danych wczytywana po kliknięciu popupa poprzez wp-json/posts/<id>
  • 152.
    Gdy mamy bardzodużo markerów • Wczytywanie markerów zależnie od widocznego obszaru mapy • Przygotowanie end-pointu, który na bazie zakresu szerokości i długości geograficznej zwróci listę markerów na danym obszarze
  • 153.
    Gdy mamy bardzodużo markerów • Wczytywanie markerów zależnie od widocznego obszaru mapy • Przygotowanie end-pointu, który na bazie zakresu szerokości i długości geograficznej zwróci listę markerów na danym obszarze
  • 154.
  • 155.
    • Znam dobrzeWordPressowy kokpit… • … umiem go modyfikować do swoich potrzeb … • … i zaoszczędzić sobie sporo czasu poprzez wykorzystanie gotowych wtyczek … • … dzięki WP-API mogę ten kokpit połączyć na front-endzie z czymkolwiek zechcę :-)
  • 156.
    • Znam dobrzeWordPressowy kokpit… • … umiem go dostosować do swoich potrzeb … • … i zaoszczędzić sobie sporo czasu poprzez wykorzystanie gotowych wtyczek … • … dzięki WP-API mogę ten kokpit połączyć na front-endzie z czymkolwiek zechcę :-)
  • 157.
    • Znam dobrzeWordPressowy kokpit… • … umiem go dostosować do swoich potrzeb … • … i zaoszczędzić sobie sporo czasu poprzez wykorzystanie gotowych wtyczek … • … dzięki WP-API mogę ten kokpit połączyć na front-endzie z czymkolwiek zechcę :-)
  • 158.
    • Znam dobrzeWordPressowy kokpit… • … umiem go dostosować do swoich potrzeb … • … i zaoszczędzić sobie sporo czasu poprzez wykorzystanie gotowych wtyczek … • … dzięki WP-API mogę ten kokpit połączyć na front-endzie z czymkolwiek zechcę :-)
  • 159.
  • 160.
  • 162.
    Lektura • Wykorzystanie taksonomiiw WP-API
 http://torquemag.io/working-taxonomies-using-json-rest-api/ • Tworzenie widżetów z użyciem WP-API
 http://webdevstudios.com/2015/03/26/how-to-create-an-auto-updating-widget-using-wp-api/ • Postęp łączenia WP-API z WordPressem
 https://github.com/WP-API/WP-API/issues/571
  • 163.
    Tomasz Dziuda Lead Developer@ @dziudek http://dziudek.pl dziudek@gavick.com
  • 164.