25 -27 April, 2014 http://camp2014.drupal.dn.ua DrupalGap Alexander Schedrov How to create native application for mobile devices based on Drupal site
Schedrov Alexander sanchiz Drupal Developer at Trellon
What is DrupalGap? Mobile Application Development Kit for Drupal Websites DrupalGap Module is the connection between mobile applications and Drupal websites (c)drupalgap.org Let's take a look, if it's true!
Support • Themes, modules • Blocks • Menus • Pages • Entities • Fields • Forms • Views • Messages • Services • Geolocation • Other tools
• You don't need a Objective-C and Java developers • For creating modules just need to write primitive JS code • Need to know how work Services • Need to know how to create custom Services endpoints and resources To create powerful mobile application
How does PhoneGap work? PhoneGap generates HTML, CSS and JavaScript and make application iOS and Android mobile devices. Apache Cordova provides access via JavaScript to device features such as the Camera, GPS, File System, Contacts, Compass, etc.
How mobile application interacts with Drupal Core Services FTW!!!:) Drupal site Application
Drupal requirements services, rest_server, taxonomy, views_datasource, views_json, drupalgap ! Development environments Google Chrome and the Ripple Emulator extension
 
 OR node.js
 cordova
 Java SDK for Android or xCode for iOS
File structure modules themes settings.js
Debug settings.js: Drupal.settings.debug = true; Logs in browser console: dpm(json_result); window.localStorage.clear(); drupalgap_alert(Fatal error', { title: ‘Alert title', buttonName: 'Done', alertCallback: function() {} }); drupalgap_set_message('Oh no!', 'error');
Themedrupalgap.settings.theme = 'amazing'; drupalgap.settings.blocks.amazing = { header: { title: {} }, navigation: { user_menu_anonymous:{ roles:{ value:['anonymous user'], mode:'include' } }, user_menu_authenticated:{ roles:{ value:['authenticated user'], mode:'include' } } }, content: { messages: {}, main: {} }, footer: { } }; http://themeroller.jquerymobile.com <div id="{:drupalgap_page_id:}" data-role="page"> {:header:} {:navigation:} {:content:} {:footer:} </div> Need to add styles to index.html page.tpl.html
Creating module with page callback • core_app (module folder) • core_app.js (module file) Drupal.modules.custom['core_app'] = {}; settings.js: /** * Implements hook_menu(). */ function core_app_menu() { var items = {}; items['homepage'] = { title: 'DCDN Sandbox', page_callback: 'core_app_homepage' }; return items; } ! function core_app_homepage() { var content = {}; content['homepage'] = { markup: 'some markup' }; return content; }
Creating Menu drupalgap.settings.menus['homepage_menu'] = { links:[ {title:'News', path:'news'}, {title:'About', path:'node/1'}, {title:'Contact', path:'contact'}, {title:'Our team', path:'team'} ] }; settings.js: Important: here might be only real paths, not aliases
Creating Blocks /** * Implements hook_block_info(). */ function core_app_block_info() { var blocks = { latest_news_block: { delta: 'latest_news_block', module: 'core_app' } }; return blocks; } ! /** * Implements hook_block_view(). */ function core_app_block_view(delta) { var content = ''; if (delta == 'latest_news_block') { content = '<h2>Latest news</h2>'; content += 'Some content...'; } return content; } Block visibility drupalgap.settings.blocks.amazing = { content: { homepage_menu: { pages:{ value:['homepage'], mode:'include' } }, latest_news_block: { pages:{ value:['homepage'], mode:'exclude' } }, users_block: { pages:{ value:['node/*', 'user/*'], mode:'include' }, roles:{ value:['authenticated user'], mode:'include' } }, }, }; !
Entity node_load(1, { success: function(node) { } }); ! node_save(node_array, { success: function(node) { } }); ! node_delete(1, { success: function(node) { } }); By default available pages: • node/%, node/%/edit • user/%, user/%/edit • taxonomy/term/%, taxonomy/term/%/edit • comment/%, comment/%/edit
Using Views Need to create page with JSON data document format (views_json module) Displaying a View in mobile app function core_team_menu() { var items = {}; items['team'] = { title: 'Our team', page_callback: 'core_team_page' } return items; }
function core_team_page() { var content = {}; content['team'] = { theme: 'view', format: ‘ul', /* ul, ol, table, unformatted_list */ path: 'mobile/team_new', /* the path to the view in Drupal */ row_callback: 'core_team_page_row', empty_callback: 'core_team_page_empty', attributes: { id: 'team-view' } }; return content; } ! function core_team_page_row(view, row) { var output = ''; output += '<img class="team-image" src="' + row.field_photo + '">'; output += l(row.title, 'node/' + row.Nid); return output; } ! function core_team_page_empty(view) { return 'Sorry, no results.'; }
function core_app_voting_form(form, form_state) { form.elements.name = { type:'textfield', title:'Name', default_value: Drupal.user.name }; form.elements.email = { title:'Email Address', type:'email', required: true, default_value: Drupal.user.mail }; form.elements.categoty = { title:'Category', type:'select', options:{ 0:'Feedback', 1:'Question' }, default_value:0 }; form.elements.comment = { title:'Comment', type:'textarea', }; form.elements.rating = { title:'Rating', type:'radios', required: true, options:{ 0:'0', 1:'+1', }, default_value:3 }; form.elements.submit = { type:'submit', value:'Submit' }; return form; } Forms
/** * Implements hook_menu(). */ function core_app_menu() { var items = {}; items['vote-form'] = { title: 'Voting form', page_callback: 'drupalgap_get_form', page_arguments:['core_app_voting_form'] }; return items; } /** * Form's validation function (optional). */ function core_app_voting_form_validate(form, form_state) { if (form_state.values.name == '') { drupalgap_form_set_error('name', 'Name is required field.'); } } ! /** * Form's submit function. */ function core_app_voting_form_submit(form, form_state) { drupalgap_set_message('Thank you ' + form_state.values.name + '!'); drupalgap_goto('news'); }
Need additional functionality? You got it! 1. Create custom services resource in Drupal module
 hook_services_resources(); 2. Create custom services call in DrupalGap module
 Drupal.services.call(options); var output = ''; Drupal.services.call({ method: 'POST', path: 'news.json', data: args, success: function(result) { output = ''; $.each(result, function(i, node) { output += node.title; }); } });
Demo
Links • http://api.drupalgap.org/ • http://www.drupalgap.org/ • http://www.drupalgap.org/troubleshoot • http://www.drupalgap.org/node/211 • https://drupal.org/node/2015065 Troubleshooting
THANK YOU! ! Email: alexander.schedrov@gmail.com Twitter: @alexschedrov FB: schedrov http://sanchiz.net

DrupalGap. How to create native application for mobile devices based on Drupal site - DrupalCamp Donetsk 2014

  • 1.
    25 -27 April,2014 http://camp2014.drupal.dn.ua DrupalGap Alexander Schedrov How to create native application for mobile devices based on Drupal site
  • 2.
  • 3.
    What is DrupalGap? MobileApplication Development Kit for Drupal Websites DrupalGap Module is the connection between mobile applications and Drupal websites (c)drupalgap.org Let's take a look, if it's true!
  • 4.
    Support • Themes, modules •Blocks • Menus • Pages • Entities • Fields • Forms • Views • Messages • Services • Geolocation • Other tools
  • 6.
    • You don'tneed a Objective-C and Java developers • For creating modules just need to write primitive JS code • Need to know how work Services • Need to know how to create custom Services endpoints and resources To create powerful mobile application
  • 7.
    How does PhoneGapwork? PhoneGap generates HTML, CSS and JavaScript and make application iOS and Android mobile devices. Apache Cordova provides access via JavaScript to device features such as the Camera, GPS, File System, Contacts, Compass, etc.
  • 8.
    How mobile applicationinteracts with Drupal Core Services FTW!!!:) Drupal site Application
  • 9.
    Drupal requirements services, rest_server,taxonomy, views_datasource, views_json, drupalgap ! Development environments Google Chrome and the Ripple Emulator extension
 
 OR node.js
 cordova
 Java SDK for Android or xCode for iOS
  • 10.
  • 11.
    Debug settings.js: Drupal.settings.debug = true; Logsin browser console: dpm(json_result); window.localStorage.clear(); drupalgap_alert(Fatal error', { title: ‘Alert title', buttonName: 'Done', alertCallback: function() {} }); drupalgap_set_message('Oh no!', 'error');
  • 12.
    Themedrupalgap.settings.theme = 'amazing'; drupalgap.settings.blocks.amazing= { header: { title: {} }, navigation: { user_menu_anonymous:{ roles:{ value:['anonymous user'], mode:'include' } }, user_menu_authenticated:{ roles:{ value:['authenticated user'], mode:'include' } } }, content: { messages: {}, main: {} }, footer: { } }; http://themeroller.jquerymobile.com <div id="{:drupalgap_page_id:}" data-role="page"> {:header:} {:navigation:} {:content:} {:footer:} </div> Need to add styles to index.html page.tpl.html
  • 13.
    Creating module withpage callback • core_app (module folder) • core_app.js (module file) Drupal.modules.custom['core_app'] = {}; settings.js: /** * Implements hook_menu(). */ function core_app_menu() { var items = {}; items['homepage'] = { title: 'DCDN Sandbox', page_callback: 'core_app_homepage' }; return items; } ! function core_app_homepage() { var content = {}; content['homepage'] = { markup: 'some markup' }; return content; }
  • 14.
    Creating Menu drupalgap.settings.menus['homepage_menu'] ={ links:[ {title:'News', path:'news'}, {title:'About', path:'node/1'}, {title:'Contact', path:'contact'}, {title:'Our team', path:'team'} ] }; settings.js: Important: here might be only real paths, not aliases
  • 15.
    Creating Blocks /** * Implementshook_block_info(). */ function core_app_block_info() { var blocks = { latest_news_block: { delta: 'latest_news_block', module: 'core_app' } }; return blocks; } ! /** * Implements hook_block_view(). */ function core_app_block_view(delta) { var content = ''; if (delta == 'latest_news_block') { content = '<h2>Latest news</h2>'; content += 'Some content...'; } return content; } Block visibility drupalgap.settings.blocks.amazing = { content: { homepage_menu: { pages:{ value:['homepage'], mode:'include' } }, latest_news_block: { pages:{ value:['homepage'], mode:'exclude' } }, users_block: { pages:{ value:['node/*', 'user/*'], mode:'include' }, roles:{ value:['authenticated user'], mode:'include' } }, }, }; !
  • 16.
    Entity node_load(1, { success: function(node){ } }); ! node_save(node_array, { success: function(node) { } }); ! node_delete(1, { success: function(node) { } }); By default available pages: • node/%, node/%/edit • user/%, user/%/edit • taxonomy/term/%, taxonomy/term/%/edit • comment/%, comment/%/edit
  • 17.
    Using Views Need tocreate page with JSON data document format (views_json module) Displaying a View in mobile app function core_team_menu() { var items = {}; items['team'] = { title: 'Our team', page_callback: 'core_team_page' } return items; }
  • 18.
    function core_team_page() { varcontent = {}; content['team'] = { theme: 'view', format: ‘ul', /* ul, ol, table, unformatted_list */ path: 'mobile/team_new', /* the path to the view in Drupal */ row_callback: 'core_team_page_row', empty_callback: 'core_team_page_empty', attributes: { id: 'team-view' } }; return content; } ! function core_team_page_row(view, row) { var output = ''; output += '<img class="team-image" src="' + row.field_photo + '">'; output += l(row.title, 'node/' + row.Nid); return output; } ! function core_team_page_empty(view) { return 'Sorry, no results.'; }
  • 20.
    function core_app_voting_form(form, form_state){ form.elements.name = { type:'textfield', title:'Name', default_value: Drupal.user.name }; form.elements.email = { title:'Email Address', type:'email', required: true, default_value: Drupal.user.mail }; form.elements.categoty = { title:'Category', type:'select', options:{ 0:'Feedback', 1:'Question' }, default_value:0 }; form.elements.comment = { title:'Comment', type:'textarea', }; form.elements.rating = { title:'Rating', type:'radios', required: true, options:{ 0:'0', 1:'+1', }, default_value:3 }; form.elements.submit = { type:'submit', value:'Submit' }; return form; } Forms
  • 21.
    /** * Implements hook_menu(). */ functioncore_app_menu() { var items = {}; items['vote-form'] = { title: 'Voting form', page_callback: 'drupalgap_get_form', page_arguments:['core_app_voting_form'] }; return items; } /** * Form's validation function (optional). */ function core_app_voting_form_validate(form, form_state) { if (form_state.values.name == '') { drupalgap_form_set_error('name', 'Name is required field.'); } } ! /** * Form's submit function. */ function core_app_voting_form_submit(form, form_state) { drupalgap_set_message('Thank you ' + form_state.values.name + '!'); drupalgap_goto('news'); }
  • 22.
    Need additional functionality?You got it! 1. Create custom services resource in Drupal module
 hook_services_resources(); 2. Create custom services call in DrupalGap module
 Drupal.services.call(options); var output = ''; Drupal.services.call({ method: 'POST', path: 'news.json', data: args, success: function(result) { output = ''; $.each(result, function(i, node) { output += node.title; }); } });
  • 23.
  • 24.
    Links • http://api.drupalgap.org/ • http://www.drupalgap.org/ •http://www.drupalgap.org/troubleshoot • http://www.drupalgap.org/node/211 • https://drupal.org/node/2015065 Troubleshooting
  • 25.
    THANK YOU! ! Email: alexander.schedrov@gmail.com Twitter:@alexschedrov FB: schedrov http://sanchiz.net