Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

316 views

Published on

Manual Plugin 제작 과정을 통해 메뉴 관리자를 통한 메뉴 생성, 도큐먼트 및 기타 코어 패키지 사용 방법을 살펴봅니다.

Published in: Software
  • Be the first to comment

  • Be the first to like this

XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

  1. 1. 1
  2. 2. 오승훈 @akasima • XE 커뮤니티 개발 그룹 • XE3 개발 • Database, Document, DynamicField, Presenter.. • XE3 게시판 플러그인 개발
 2
  3. 3. 목차 33 플러그인 제작 플러그인 생성 관리자 사이트맵에서 메뉴 생성 라우트 등록 인터셉션 데이터 베이스
  4. 4. Manual 플러그인 4
  5. 5. Manual 플러그인 요구사항 5 카테고리 도큐먼트
  6. 6. 관리자 > 사이트맵에서 메뉴 생성 6
  7. 7. 플러그인 생성 7
  8. 8. 플러그인 규칙 디렉토리이름은 소문자, 숫자와 언더스코어(언더바)로 작성 plugin.php, composer.json 필수 8
  9. 9. plugin.php - 필수 요소1 9 <?php
 namespace Akasima;
 
 use …;
 
 class Plugin extends AbstractPlugin
 {
 /**
 * 이 메소드는 활성화(activate) 된 플러그인이 부트될 때 항상 실행됩니다.
 *
 * @return void
 */
 public function boot()
 {
 }
  10. 10. AbstractPlugin 10 http://api.xpressengine.io
  11. 11. 11 플러그인 코어 패키지 플러그인 플러그인 코어 패키지는 플러그인에게 묻고 싶은게 많습니다.
  12. 12. 12 <?php
 
 abstract class AbstractPlugin
 {
 public static function getId() 
 public static function getIdWith($postfix = '', $delimiter = '::')
 public function activate($installedVersion = null)
 
 public function deactivate($installedVersion = null)
 
 public function install()
 
 public function checkInstall($installedVersion = null)
 
 public function update($installedVersion = null)
 
 public function checkUpdate($currentVersion = null)
 
 public function uninstall()
 
 abstract public function boot();
 
 public function getSettingsURI()
 
 public static function getPath($path = '')
 
 public static function asset($path, $secure =
  13. 13. composer.json - 필수 요소2 13 {
 "name": "xpressengine-plugin/ my_plugin",
 "description": "플러그인소개",
 "keywords": [
 "xpressengine",
 "plugin"
 ],
 "license": "LGPL-2.0",
 "version": "1.0.0",
 "type": "xpressengine-plugin",
 "support": {
 "email": "email@email.com"
 },
 "authors": [
 {
 "name": "input your name",
 "email": "input@your.email",
 "homepage": "http:// mysite.com",
 "role": "Developer"
 }
 ],
 "extra": {
 "xpressengine": {
 "title": "my_plugin_title",
 "icon": "myicon.png",
 "component": []
 }
 },
 "repositories": [
 {
 "type": "composer",
 "url": "http:// packagist.xpressengine.io/"
 }
 ],
 "require": {
 
 },
 "autoload": {
 "psr-4": {
 "Akasima": "src/"
 }
 }
 }
 app/Console/Commands/stubs/composer.json.stub 복사
  14. 14. 플러그인 생성 완료 14 composer.json pluing.php
  15. 15. 플러그인 생성 확인 15
  16. 16. 플러그인 켜기 16
  17. 17. 플러그인 동작 확인 17 public function boot()
 {
 $this->route();
 }
 
 protected function route()
 {
 // implement code
 
 Route::fixed($this->getId(), function () {
 Route::get('/', [
 'as' => 'my_plugin::index',
 'uses' => function (Request $request) {
 echo "Hello World";
 }
 ]);
 });
 }
  18. 18. 어렵다!!
  19. 19. 간단한 command 제공 19 php artisan make:plugin my_plugin Akasima my_plugin_title
  20. 20. 20 vendor view 생성된 디렉토리 assets src composer.json pluing.php js, css, image PHP source 템플릿
  21. 21. 21 메뉴 추가
  22. 22. 22 컴포넌트? my_plugin 테마 스킨 매뉴얼 위젯 게시판 스킨 플러그인은 설치/실행 등 기능 꾸러미 관리의 목적 플러그인은 여러개의 기능 요소로 이루어짐 (컴포넌트가 있을 수 있음)
  23. 23. 23 컴포넌트 Interface XE3 ModuleAbstractModule 모듈 SkinAbstractSkin 스킨 ThemeAbstractTheme 테마 WidgetAbstractWidget 위젯 UIObjectAbstractUIObject UI Object DynamicFieldAbstractType FieldType DynamicFieldAbstractSkin FieldSkin
  24. 24. 24 ComponentInterface
  25. 25. 25 ComponentInterface
  26. 26. 26 컴포넌트 ID 플러그인 코어 패키지 my_plu 테마 스킨 매뉴 위젯 게시판 저 등록좀 해주세요~ 그리고 저 한테 컴포넌트도 있으니까 이 애들도 등록할께요
  27. 27. 27 컴포넌트 ID 플러그인 코어 패키지 my_plu 테마 스킨 매뉴 위젯 게시판 저 등록좀 해주세요~ 그리고 저 한테 컴포넌트도 있으니까 이 애들도 등록할께요 플러그인 코어 패키지 컴포넌트
  28. 28. 28 컴포넌트 ID 플러그인 코어 패키지 my_plu 테마 스킨 매뉴 위젯 게시판 Register 코어 패키지 에 컴포넌트 등록
  29. 29. 29 컴포넌트 ID 등록된 컴포넌트 리스트
  30. 30. 컴포넌트 ID란? module/board@board module/my_plugin@manual 컴포넌트종류/플러그인@컴포넌트이름
  31. 31. 컴포넌트 ID module/board@board module/my_plugin@manual // my_plugin 에서 등록한 게시판 모듈용 redSkin module/board@board/skin/my_plugin@redSkin // my_plugin 에서 등록한 매뉴얼 모듈용 redSkin module/my_plugin@manual@skin/my_plugin@blueSkin 컴포넌트종류/플러그인@컴포넌트이름/컴포넌트종류/플러그인@컴포넌트이름 대상아이디/컴포넌트종류/플러그인@컴포넌트이름
  32. 32. 32 src/Manual.php <?php
 namespace Akasima;
 
 use XpressengineModuleAbstractModule;
 
 class Manual extends AbstractModule
 {
 public static function getInstanceSettingURI($instanceId)
 {
 }
 
 public function createMenuForm()
 {
 }
 
 public function storeMenu($instanceId, $menuTypeParams, $itemParams)
 {
 }
 
 public function editMenuForm($instanceId)
 {

  33. 33. 33 MenuTypeInterface
  34. 34. 34 Composer.json - 컴포넌트 등록 "extra": {
 "xpressengine": {
 "title": "my_plugin_title",
 "icon": "myicon.png",
 "component": {
 “module/my_plugin@manual": {
 "class": "AkasimaManual",
 "name": "Manual",
 "description": "akasima 매뉴얼 모듈",
 "screenshot" : [
 “/plugins/my_plugin/assets/img/screenshots/ akasimaManual.jpg"
 ]
 }
 }
 }
 },
  35. 35. 35 메뉴 컴포넌트 추가
  36. 36. 36 메뉴를 추가할 수 있습니다.
  37. 37. 37 Routing 라우팅 설정이 없음
  38. 38. 38 Routing 등록 공식사이트, Laravel 문서 참고
  39. 39. 39 Routing 등록 http://xpressengine.io/docs/3.0/Routing
  40. 40. 40 
 class Manual extends AbstractModule
 {
 public static function boot()
 {
 Route::instance(self::getId(), function () {
 Route::get('', ['as' => 'index', 'uses' => 'UserController@index']);
 Route::get('/edit', ['as' => 'edit', 'uses' => 'UserController@edit']);
 Route::post('/update', ['as' => 'update', 'uses' => 'UserController@update']);
 }, ['namespace' => 'Akasima']);
 } Routing 등록
  41. 41. 41 namespace Akasima;
 
 use AppHttpControllersController;
 
 class UserController extends Controller
 {
 public function index()
 {
 return Presenter::make('my_plugin::views.manual.index');
 }
 
 public function edit()
 {
 return 'edit';
 }
 
 public function update()
 {
 return 'update';
 }
 } Routing 등록 UserController.php
  42. 42. 42 <strong>메인페이지 입니다</strong>
 
 <a href="{{instanceRoute('edit')}}">수정페이지</a>
 view blade views/manual/index.blade.php
  43. 43. 43
  44. 44. 44 하고 싶은 이야기는 많지만.. 12월 12일 오픈 세미나가 있습니다. 더 자세한 얘기는 XEHub 에서
  45. 45. 45 Interception
  46. 46. 46 Interception Hook Event Trigger
  47. 47. 47 AOP interception(가로채는) 을 구현하기 위해 AOP 를 도입
  48. 48. AOP 관점지향 프로그래밍 Aspect Oriented Programming [Documentation]
  49. 49. 49 Proxy 생성 Service provider 에 정의되어있습니다.
  50. 50. 50 Interception 사용 인터셉션 등록은 plugin boot() 메소드에 정의 intercept(
 'Comment@add',
 'notification.comment.add',
 function ($addFunc, CommentEntity $comment, MemberEntityInterface $user = null) { 
 /**
 * @var $commentNotificator CommentNotificator
 */
 $commentNotificator = app('xe.notification.notificator.comment');
 $commentNotificator->notify($comment);
 
 $commentEntity = $addFunc($comment, $user);
 
 return $commentEntity;
 }
 );
  51. 51. 51 Interception 사용 댓글 작성시 알림 발송(알림센터) intercept(
 'Comment@add',
 'notification.comment.add',
 function ($addFunc, CommentEntity $comment, MemberEntityInterface $user = null) { 
 /**
 * @var $commentNotificator CommentNotificator
 */
 $commentNotificator = app('xe.notification.notificator.comment');
 $commentNotificator->notify($comment);
 
 $commentEntity = $addFunc($comment, $user);
 
 return $commentEntity;
 }
 ); 동작 시점 코드 실제 동작 대상 실행
  52. 52. 52 Interception 사용 댓글 작성시 알림 발송 - 댓글 intercept(
 'Comment@add',
 'notification.comment.add',
 function ($addFunc, CommentEntity $comment, MemberEntityInterface $user = null) { 
 $commentEntity = $addFunc($comment, $user);
 
 /**
 * @var $commentNotificator CommentNotificator
 */
 $commentNotificator = app('xe.notification.notificator.comment');
 $commentNotificator->notify($comment);
 
 return $commentEntity;
 }
 );
  53. 53. 데이타 베이스 사용하기 53
  54. 54. 데이타 베이스 54
  55. 55. 트랜잭션 55 intercept(
 'Comment@add',
 'notification.comment.add',
 function ($addFunc, CommentEntity $comment, MemberEntityInterface $user = null) { 
 XeDB::beginTransaction();
 
 $commentNotificator = app('xe.notification.notificator.comment');
 $commentNotificator->notify($comment);
 
 $commentEntity = $addFunc($comment, $user);
 
 XeDB::commit(); 
 return $commentEntity;
 }
 );
  56. 56. 트랜잭션 56 intercept(
 'Comment@add',
 'notification.comment.add',
 function ($addFunc, CommentEntity $comment, MemberEntityInterface $user = null) { 
 XeDB::beginTransaction();
 
 $commentNotificator = app('xe.notification.notificator.comment');
 $commentNotificator->notify($comment);
 
 $commentEntity = $addFunc($comment, $user);
 
 XeDB::commit(); 
 return $commentEntity;
 }
 );
  57. 57. 데이터 베이스 테이블 57 if (Schema::hasTable(‘table_name') === false) {
 Schema::create('table_name', function (Blueprint $table) {
 $table->increments('id');
 $table->string('instanceId', 255);
 $table->string('title', 255);
 
 $table->index(array('title'));
 });
 }
  58. 58. 디버깅 58 /storage/log/laravel.log 참고 APP_DEBUG=true /.env
  59. 59. 캐시 삭제 59 php artisan xeCache:clear
  60. 60. 감사합니다 60

×