MTDDC 2010.2.5 Tokyo - Brand new API

Six Apart KK
Six Apart KKSix Apart KK
MTDDC 2010.2.5 Tokyo - Brand new API
Brand New API


Movable Type Developers & Designers Conference
              2010.2.5 in Tokyo

            Yuji Takayama,Six Apart
r y!
 u ng
H
Whatʼs brand new?
• Website
• Theme Framework
• Revision History Framework
• User Dashboard
• Everything is UTF-8
• Permission API
• Menu Structure
• Dynamic Publishing
• User Interface
• Custom Fields
MTDDC 2010.2.5 Tokyo - Brand new API
What is “Website”?
Website is ...
The root object of the
  Movable Type 5
How can I use the
 website object
use MT::Website;

my $website_id = 1;
my $website =
    MT::Website-
>load($website_id)
    or die;
$website->name(‘New Website’);
$website->save or die;
itʼs easy
use MT::Blog;
use MT::Website;

my $website_id = 1;
my $website =
    MT::Website->load($website_id)
        or die;
my $blog = new MT::Blog;
$website->add_blog($blog);
my $blogs = $website->blogs;
All blogs belongs to
     the website
$website->site_url;
$website->site_path;
$website->name;
$website->description;
like a blog?

  Right.
• The website uses same table as the
  blog.

• The class of the website is “website”,
  also the class of the blog is “blog”.

• The blog has parent_id that means the
  belonging website.
mysql> select blog_id, blog_class, blog_parent_id
from mt_blog;

+---------+------------+----------------+
| blog_id | blog_class | blog_parent_id |
+---------+------------+----------------+
|       1 | website    |           NULL |
|       2 | blog       |              1 |
|       3 | blog       |              1 |
|       4 | blog       |              1 |
|       5 | website    |           NULL |
+---------+------------+----------------+
5 rows in set (0.01 sec)
new template tags
•   MTWebsites                •   MTWebsitePath

•   MTIfWebsite?              •   MTWebsiteTimezone

•   MTWebsiteIfCCLicense      •   MTWebsiteCCLicenseURL

•   MTWebsiteHasBlog          •   MTWebsiteCCLicenseImage

•   MTBlogParentWebsite       •   MTWebsiteFileExtension

•   MTWebsiteIfCommentsOpen   •   MTWebsiteHost

•   MTWebsiteID               •   MTWebsiteRelativeURL

•   MTWebsiteName             •   MTWebsiteThemeID

•   MTWebsiteDescription      •   MTWebsiteCommentCount

•   MTWebsiteLanguage         •   MTWebsitePingCount

•   MTWebsiteURL              •   MTWebsitePageCount
new template tags
•   MTWebsites                •   MTWebsitePath

•   MTIfWebsite?              •   MTWebsiteTimezone

•   MTWebsiteIfCCLicense      •   MTWebsiteCCLicenseURL

•   MTWebsiteHasBlog          •   MTWebsiteCCLicenseImage

•   MTBlogParentWebsite       •   MTWebsiteFileExtension

•   MTWebsiteIfCommentsOpen   •   MTWebsiteHost

•   MTWebsiteID               •   MTWebsiteRelativeURL

•   MTWebsiteName             •   MTWebsiteThemeID

•   MTWebsiteDescription      •   MTWebsiteCommentCount

•   MTWebsiteLanguage         •   MTWebsitePingCount

•   MTWebsiteURL              •   MTWebsitePageCount
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
Now, Movable Type
has a revision history
   management.
By default, only the entry
and the template use it.
But....
You can use it in your
      plug-in.
package MT::Object::MyModel
use base qw ( MT::Object
MT::Revisable );

__PACKAGE__->install_properties({
    ‘id’ => ‘integer not null
auto_increment’,
    ‘text’ => ‘string(255)
revisioned’
    # ...
});

1;
package MT::Object::MyModel
use base qw ( MT::Object
MT::Revisable );

__PACKAGE__->install_properties({
    ‘id’ => ‘integer not null
auto_increment’,
    ‘text’ => ‘string(255)
revisioned’
    # ...
});

1;
package MT::Object::MyModel
use base qw ( MT::Object
MT::Revisable );

__PACKAGE__->install_properties({
    ‘id’ => ‘integer not null
auto_increment’,
    ‘text’ => ‘string(255)
revisioned’
    # ...
});

1;
itʼs easy
Movable Type does
 save a revision
  automatically.
If your object related
    to other object
You must override
 ʻpack_revisionʼ and
  ʻunpack_revisionʼ
method on your object.
sub pack_revision {
    my $obj = shift;
    my $values = MT::Revisable::pack_revision( $obj );

    # add category placements and tag associations
    my ( @tags, @cats );
    if ( my $tags = $obj->get_tag_objects ) {
        @tags = map { $_->id } @$tags
            if @$tags;
    }
    # a revision may remove all the tags
    $values->{__rev_tags} = @tags;

    my $primary = $obj->category;
    if ( my $cats = $obj->categories ) {
        @cats = map { [
            $_->id,
            $_->id == $primary->id ? 1 : 0
        ] } @$cats
            if @$cats;
    }
    # a revision may remove all the categories
    $values->{__rev_cats} = @cats;

    $values;
}
}

sub unpack_revision {                             if ( my $rev_cats = delete $packed_obj-
    my $obj = shift;                          >{__rev_cats} ) {
    my ($packed_obj) = @_;                            $obj->clear_cache('category');
    MT::Revisable::unpack_revision( $obj,             $obj->clear_cache('categories');
@_ );
                                                      my ( $cat, @cats );
    # restore category placements and tag             if ( @$rev_cats ) {
associations                                              my ($primary) = grep { $_->[1] }
    if ( my $rev_tags = delete $packed_obj-   @$rev_cats;
>{__rev_tags} ) {                                         $cat = MT::Category-
        delete $obj->{__tags};                >lookup( $primary->[0] );
        delete $obj->{__tag_objects};                     my $cats = MT::Category-
        MT::Tag->clear_cache(datasource =>    >lookup_multi([ map { $_->[0] } @
$obj->datasource,                             $rev_cats ]);
             ($obj->blog_id ? (blog_id =>                 my @cats = sort { $a->label cmp
$obj->blog_id) : ()));                        $b->label } grep { defined } @$cats;
                                                          $obj->{__missing_cats_rev} = 1
        require MT::Memcached;                                 if scalar( @cats ) !=
        MT::Memcached->instance-              scalar( @$cats );
>delete( $obj->tag_cache_key );                       }
                                                      $obj->cache_property( 'category',
        if ( @$rev_tags ) {                   undef, $cat );
            my $lookups = MT::Tag-                    $obj->cache_property( 'categories',
>lookup_multi($rev_tags);                     undef, @cats );
            my @tags = grep { defined } @         }
$lookups;                                     }
            $obj->{__tags} = [ map { $_-
>name } @tags ];
            $obj->{__tag_objects} = @tags;
            $obj->{__missing_tags_rev} = 1
                 if scalar( @tags ) !=
scalar( @$lookups );
        }
        else {
            $obj->{__tags} = [];
            $obj->{__tag_objects} = [];
        }
See MT::Entry
MTDDC 2010.2.5 Tokyo - Brand new API
perldoc MT::Revisable
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
Itʼs your Home to start
       all actions.
Also, you can add
your own widget here
widgets:
  FeedsWidget:
  label: Feed Aggregate
  template: tmpl/widget.tmpl
  handler:
$FeedWidget::Widget::hdlr_widget
  set: main
  singular: 1
  view: blog
widgets:
  FeedsWidget:
  label: Feed Aggregate
  template: tmpl/widget.tmpl
  handler:
$FeedWidget::Widget::hdlr_widget
  set: main
  singular: 1
  view: blog
widgets:
  FeedsWidget:
  label: Feed Aggregate
  template: tmpl/widget.tmpl
  handler:
$FeedWidget::Widget::hdlr_widget
  set: main
  singular: 1
  view: blog
widgets:
  FeedsWidget:
  label: Feed Aggregate
  template: tmpl/widget.tmpl
  handler:
$FeedWidget::Widget::hdlr_widget
  set: main
  singular: 1
  view: blog
widgets:
  FeedsWidget:
  label: Feed Aggregate
  template: tmpl/widget.tmpl
  handler:
$FeedWidget::Widget::hdlr_widget
  set: main
  singular: 1
  view: blog
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
Everything is UTF-8
Now, all strings in the
 Movable Type 5 is
   utf-8 flagged.
before
Movable Type 5
You must encode object
       by yourself
  if PublishCharset is
       not UTF-8.
sub _hdlr_my_tag {
    my ( $ctx, $args ) = @_;
    my $obj = MT::Entry->load(
        $args->{id});
    my $data = $obj->text;

    # do something...

    return MT::I18N::encode_text(
        $data, ‘utf-8’ );
}
sub _hdlr_my_tag {
    my ( $ctx, $args ) = @_;
    my $obj = MT::Entry->load(
        $args->{id});
    my $data = $obj->text;

    # do something...

    return MT::I18N::encode_text(
        $data, ‘utf-8’ );
}
from now,
You are freed from
obligation of Encode.
sub _hdlr_my_tag {
    my ( $ctx, $args ) = @_;
    my $obj = MT::Entry->load(
        $args->{id});
    my $data = $obj->text;

    # do something...

    return $data;
}
You must
encode/decode
 your own data
    when...
• Communicating with an external
  network.

• File input/output without MT::FileMgr.
• Saving valuesto columns declared in
  MT::Object blob format.
sub _hdlr_my_tag {
    my ( $ctx, $args ) = @_;
    my $data;

    # received from web service.

    return Encode::decode_utf8(
        $data );
}
sub _hdlr_my_tag {
    my ( $ctx, $args ) = @_;
    my $data;

    # received from web service.

    return Encode::decode_utf8(
        $data );
}
MTDDC 2010.2.5 Tokyo - Brand new API
Weʼve aimed to...


• easy to understanding
An user who has ‘manage_pages’
permission. Which actions this
user can do?
Movable Type 4...
  $app->can_manage_pages();

Movable Type 5...
  $app->can_do(
‘remove_all_trackbacks_on_webpages’
  );

manage_pages:
 permitted_action:
  remove_all_trackbacks_on_webpages: 1
MTDDC 2010.2.5 Tokyo - Brand new API
See MT::Core
load_core_permissions
Weʼve aimed to...


• easy to understanding
• Can be extensible
permissions:
   blog.your_permission:
       group: blog_admin
       label: Your New Permission
       order: 350
       permitted_action:
           your_action: 1
           your_other_action: 1
MTDDC 2010.2.5 Tokyo - Brand new API
Specify the role group.


• blog_admin
• auth_pub           • sys_admin
• blog_upload          (only system
                       level)
• blog_comment
• blog_design
label
The display name of the permission.
order
Ordering the permission in its role group
permitted_action
Hash to define a list of actions permitted for hte
use who has this permission.
inherit_from
A list of inheritance origins for this permission.
Defined by references to the list.
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
Of course, you can
add your menu by
      plugin.
applications:
  cms:
    menus:
       tools:my_menu:
         label: Your Menu Label
         mode: your_mode
         order: 150
         view: blog
You can display your
   menu on any
     dashboard
applications:
  cms:
    menus:
       tools:my_menu:
         label: Your Menu Label
         mode: your_mode
         order: 150
         view: blog
applications:
  cms:
    menus:
       tools:my_menu:
         label: Your Menu Label
         mode: your_mode
         order: 150
         view: blog
MTDDC 2010.2.5 Tokyo - Brand new API
You can restrict your
menu by permission.
permissions:
   blog.your_permission:
       permitted_action:
           your_action: 1
applications:
 cms:
  menus:
   tools:my_menu:
    label: Your Menu Label
    mode: your_mode
    order: 150
    view: blog
    permit_action: your_action
If your plugin still
supports MT4 and MT5
menus:
 create:my_object:
  condition: >
  sub {
    MT->product_version < 5; }
 entries:create:
  condition: >
  sub {
    MT->product_version >= 5; }
MTDDC 2010.2.5 Tokyo - Brand new API
jquery
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
and... jquery-ui Ready.
CSS
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
More detail...

http://www.slideshare.net/
   swordbreaker/plugin
Thank you for listening.
1 of 110

More Related Content

What's hot(20)

The State of LithiumThe State of Lithium
The State of Lithium
Nate Abele2.3K views
Doctrine 2Doctrine 2
Doctrine 2
zfconfua1.7K views
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
Hugo Hamon14.8K views
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
Azim Kurtaliev1.7K views
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
Bill Chang5K views
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage1.5K views
Agile database access with CakePHP 3Agile database access with CakePHP 3
Agile database access with CakePHP 3
José Lorenzo Rodríguez Urdaneta17.9K views
Internationalizing CakePHP ApplicationsInternationalizing CakePHP Applications
Internationalizing CakePHP Applications
Pierre MARTIN5.8K views
Command Bus To Awesome TownCommand Bus To Awesome Town
Command Bus To Awesome Town
Ross Tuck7.2K views
Perl object ?Perl object ?
Perl object ?
ℕicolas ℝ.340 views
Intro programacion funcionalIntro programacion funcional
Intro programacion funcional
NSCoder Mexico306 views
Revisiting  SOLID Principles Revisiting  SOLID Principles
Revisiting SOLID Principles
Anis Ahmad72 views

Viewers also liked(20)

Data API ことはじめData API ことはじめ
Data API ことはじめ
Yuji Takayama1.3K views
Introducing C# in AWS LambdaIntroducing C# in AWS Lambda
Introducing C# in AWS Lambda
Atsushi Fukui1.7K views
20161111 java one2016-feedback20161111 java one2016-feedback
20161111 java one2016-feedback
Takashi Ito567 views
Introduction to AWS X-RayIntroduction to AWS X-Ray
Introduction to AWS X-Ray
Keisuke Nishitani8.5K views
Serverless meetup02 openwhiskServerless meetup02 openwhisk
Serverless meetup02 openwhisk
Hideaki Tokida9.5K views
The Internal of Serverless PluginsThe Internal of Serverless Plugins
The Internal of Serverless Plugins
Terui Masashi2.3K views
What's new with ServerlessWhat's new with Serverless
What's new with Serverless
Keisuke Nishitani1.5K views
Serverless RevolutionServerless Revolution
Serverless Revolution
Keisuke Nishitani2.7K views
Serverless for DevelopersServerless for Developers
Serverless for Developers
Amazon Web Services1.1K views

Similar to MTDDC 2010.2.5 Tokyo - Brand new API

WordPress plugin #3WordPress plugin #3
WordPress plugin #3giwoolee
364 views68 slides
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011Yusuke Wada
2.7K views43 slides
Twig tips and tricksTwig tips and tricks
Twig tips and tricksJavier Eguiluz
199.3K views185 slides

Similar to MTDDC 2010.2.5 Tokyo - Brand new API(20)

Hacking Movable TypeHacking Movable Type
Hacking Movable Type
Stefano Rodighiero2.2K views
WordPress plugin #3WordPress plugin #3
WordPress plugin #3
giwoolee364 views
Blog Hacks 2011Blog Hacks 2011
Blog Hacks 2011
Yusuke Wada2.7K views
Twig tips and tricksTwig tips and tricks
Twig tips and tricks
Javier Eguiluz199.3K views
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
Shinya Ohyanagi1.3K views
Introduction To MocoIntroduction To Moco
Introduction To Moco
Naoya Ito2K views
Extending MooseExtending Moose
Extending Moose
sartak2.3K views
Php on the desktop and php gtk2Php on the desktop and php gtk2
Php on the desktop and php gtk2
Elizabeth Smith4.2K views
Bag Of Tricks From IusethisBag Of Tricks From Iusethis
Bag Of Tricks From Iusethis
Marcus Ramberg6.4K views
DBIx::Skinnyと仲間たちDBIx::Skinnyと仲間たち
DBIx::Skinnyと仲間たち
Ryo Miyake1.9K views
Speed Things Up with TransientsSpeed Things Up with Transients
Speed Things Up with Transients
Cliff Seal1.5K views
Zend framework serviceZend framework service
Zend framework service
Michelangelo van Dam803 views
Zend framework serviceZend framework service
Zend framework service
Michelangelo van Dam1.3K views
About Data::ObjectDriverAbout Data::ObjectDriver
About Data::ObjectDriver
Yoshiki Kurihara1.6K views
Ruby on rails Ruby on rails
Ruby on rails
Mohit Jain722 views
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
Jano Suchal598 views
Add loop shortcodeAdd loop shortcode
Add loop shortcode
Peter Baylies316 views
php2.pptxphp2.pptx
php2.pptx
ElieNGOMSEU4 views

More from Six Apart KK(20)

Movable Type for AWS Starter Guide (en)Movable Type for AWS Starter Guide (en)
Movable Type for AWS Starter Guide (en)
Six Apart KK18.5K views
Movable type for AWS Starter GuideMovable type for AWS Starter Guide
Movable type for AWS Starter Guide
Six Apart KK11.2K views
Six Apart UniBaaS 解説書Six Apart UniBaaS 解説書
Six Apart UniBaaS 解説書
Six Apart KK2.6K views
Mtddc meetup kyushu_2013_keynote_2Mtddc meetup kyushu_2013_keynote_2
Mtddc meetup kyushu_2013_keynote_2
Six Apart KK2.1K views
Azure と MT のフシギな関係Azure と MT のフシギな関係
Azure と MT のフシギな関係
Six Apart KK1.8K views
MTDDC Tokyo 2012MTDDC Tokyo 2012
MTDDC Tokyo 2012
Six Apart KK1.3K views

MTDDC 2010.2.5 Tokyo - Brand new API

  • 2. Brand New API Movable Type Developers & Designers Conference 2010.2.5 in Tokyo Yuji Takayama,Six Apart
  • 3. r y! u ng H
  • 5. • Website • Theme Framework • Revision History Framework • User Dashboard
  • 6. • Everything is UTF-8 • Permission API • Menu Structure • Dynamic Publishing • User Interface • Custom Fields
  • 10. The root object of the Movable Type 5
  • 11. How can I use the website object
  • 12. use MT::Website; my $website_id = 1; my $website = MT::Website- >load($website_id) or die; $website->name(‘New Website’); $website->save or die;
  • 14. use MT::Blog; use MT::Website; my $website_id = 1; my $website = MT::Website->load($website_id) or die; my $blog = new MT::Blog; $website->add_blog($blog); my $blogs = $website->blogs;
  • 15. All blogs belongs to the website
  • 17. like a blog? Right.
  • 18. • The website uses same table as the blog. • The class of the website is “website”, also the class of the blog is “blog”. • The blog has parent_id that means the belonging website.
  • 19. mysql> select blog_id, blog_class, blog_parent_id from mt_blog; +---------+------------+----------------+ | blog_id | blog_class | blog_parent_id | +---------+------------+----------------+ | 1 | website | NULL | | 2 | blog | 1 | | 3 | blog | 1 | | 4 | blog | 1 | | 5 | website | NULL | +---------+------------+----------------+ 5 rows in set (0.01 sec)
  • 20. new template tags • MTWebsites • MTWebsitePath • MTIfWebsite? • MTWebsiteTimezone • MTWebsiteIfCCLicense • MTWebsiteCCLicenseURL • MTWebsiteHasBlog • MTWebsiteCCLicenseImage • MTBlogParentWebsite • MTWebsiteFileExtension • MTWebsiteIfCommentsOpen • MTWebsiteHost • MTWebsiteID • MTWebsiteRelativeURL • MTWebsiteName • MTWebsiteThemeID • MTWebsiteDescription • MTWebsiteCommentCount • MTWebsiteLanguage • MTWebsitePingCount • MTWebsiteURL • MTWebsitePageCount
  • 21. new template tags • MTWebsites • MTWebsitePath • MTIfWebsite? • MTWebsiteTimezone • MTWebsiteIfCCLicense • MTWebsiteCCLicenseURL • MTWebsiteHasBlog • MTWebsiteCCLicenseImage • MTBlogParentWebsite • MTWebsiteFileExtension • MTWebsiteIfCommentsOpen • MTWebsiteHost • MTWebsiteID • MTWebsiteRelativeURL • MTWebsiteName • MTWebsiteThemeID • MTWebsiteDescription • MTWebsiteCommentCount • MTWebsiteLanguage • MTWebsitePingCount • MTWebsiteURL • MTWebsitePageCount
  • 25. Now, Movable Type has a revision history management.
  • 26. By default, only the entry and the template use it.
  • 28. You can use it in your plug-in.
  • 29. package MT::Object::MyModel use base qw ( MT::Object MT::Revisable ); __PACKAGE__->install_properties({ ‘id’ => ‘integer not null auto_increment’, ‘text’ => ‘string(255) revisioned’ # ... }); 1;
  • 30. package MT::Object::MyModel use base qw ( MT::Object MT::Revisable ); __PACKAGE__->install_properties({ ‘id’ => ‘integer not null auto_increment’, ‘text’ => ‘string(255) revisioned’ # ... }); 1;
  • 31. package MT::Object::MyModel use base qw ( MT::Object MT::Revisable ); __PACKAGE__->install_properties({ ‘id’ => ‘integer not null auto_increment’, ‘text’ => ‘string(255) revisioned’ # ... }); 1;
  • 33. Movable Type does save a revision automatically.
  • 34. If your object related to other object
  • 35. You must override ʻpack_revisionʼ and ʻunpack_revisionʼ method on your object.
  • 36. sub pack_revision { my $obj = shift; my $values = MT::Revisable::pack_revision( $obj ); # add category placements and tag associations my ( @tags, @cats ); if ( my $tags = $obj->get_tag_objects ) { @tags = map { $_->id } @$tags if @$tags; } # a revision may remove all the tags $values->{__rev_tags} = @tags; my $primary = $obj->category; if ( my $cats = $obj->categories ) { @cats = map { [ $_->id, $_->id == $primary->id ? 1 : 0 ] } @$cats if @$cats; } # a revision may remove all the categories $values->{__rev_cats} = @cats; $values; }
  • 37. } sub unpack_revision { if ( my $rev_cats = delete $packed_obj- my $obj = shift; >{__rev_cats} ) { my ($packed_obj) = @_; $obj->clear_cache('category'); MT::Revisable::unpack_revision( $obj, $obj->clear_cache('categories'); @_ ); my ( $cat, @cats ); # restore category placements and tag if ( @$rev_cats ) { associations my ($primary) = grep { $_->[1] } if ( my $rev_tags = delete $packed_obj- @$rev_cats; >{__rev_tags} ) { $cat = MT::Category- delete $obj->{__tags}; >lookup( $primary->[0] ); delete $obj->{__tag_objects}; my $cats = MT::Category- MT::Tag->clear_cache(datasource => >lookup_multi([ map { $_->[0] } @ $obj->datasource, $rev_cats ]); ($obj->blog_id ? (blog_id => my @cats = sort { $a->label cmp $obj->blog_id) : ())); $b->label } grep { defined } @$cats; $obj->{__missing_cats_rev} = 1 require MT::Memcached; if scalar( @cats ) != MT::Memcached->instance- scalar( @$cats ); >delete( $obj->tag_cache_key ); } $obj->cache_property( 'category', if ( @$rev_tags ) { undef, $cat ); my $lookups = MT::Tag- $obj->cache_property( 'categories', >lookup_multi($rev_tags); undef, @cats ); my @tags = grep { defined } @ } $lookups; } $obj->{__tags} = [ map { $_- >name } @tags ]; $obj->{__tag_objects} = @tags; $obj->{__missing_tags_rev} = 1 if scalar( @tags ) != scalar( @$lookups ); } else { $obj->{__tags} = []; $obj->{__tag_objects} = []; }
  • 43. Itʼs your Home to start all actions.
  • 44. Also, you can add your own widget here
  • 45. widgets: FeedsWidget: label: Feed Aggregate template: tmpl/widget.tmpl handler: $FeedWidget::Widget::hdlr_widget set: main singular: 1 view: blog
  • 46. widgets: FeedsWidget: label: Feed Aggregate template: tmpl/widget.tmpl handler: $FeedWidget::Widget::hdlr_widget set: main singular: 1 view: blog
  • 47. widgets: FeedsWidget: label: Feed Aggregate template: tmpl/widget.tmpl handler: $FeedWidget::Widget::hdlr_widget set: main singular: 1 view: blog
  • 48. widgets: FeedsWidget: label: Feed Aggregate template: tmpl/widget.tmpl handler: $FeedWidget::Widget::hdlr_widget set: main singular: 1 view: blog
  • 49. widgets: FeedsWidget: label: Feed Aggregate template: tmpl/widget.tmpl handler: $FeedWidget::Widget::hdlr_widget set: main singular: 1 view: blog
  • 54. Now, all strings in the Movable Type 5 is utf-8 flagged.
  • 56. You must encode object by yourself if PublishCharset is not UTF-8.
  • 57. sub _hdlr_my_tag { my ( $ctx, $args ) = @_; my $obj = MT::Entry->load( $args->{id}); my $data = $obj->text; # do something... return MT::I18N::encode_text( $data, ‘utf-8’ ); }
  • 58. sub _hdlr_my_tag { my ( $ctx, $args ) = @_; my $obj = MT::Entry->load( $args->{id}); my $data = $obj->text; # do something... return MT::I18N::encode_text( $data, ‘utf-8’ ); }
  • 60. You are freed from obligation of Encode.
  • 61. sub _hdlr_my_tag { my ( $ctx, $args ) = @_; my $obj = MT::Entry->load( $args->{id}); my $data = $obj->text; # do something... return $data; }
  • 62. You must encode/decode your own data when...
  • 63. • Communicating with an external network. • File input/output without MT::FileMgr. • Saving valuesto columns declared in MT::Object blob format.
  • 64. sub _hdlr_my_tag { my ( $ctx, $args ) = @_; my $data; # received from web service. return Encode::decode_utf8( $data ); }
  • 65. sub _hdlr_my_tag { my ( $ctx, $args ) = @_; my $data; # received from web service. return Encode::decode_utf8( $data ); }
  • 67. Weʼve aimed to... • easy to understanding
  • 68. An user who has ‘manage_pages’ permission. Which actions this user can do?
  • 69. Movable Type 4... $app->can_manage_pages(); Movable Type 5... $app->can_do( ‘remove_all_trackbacks_on_webpages’ ); manage_pages: permitted_action: remove_all_trackbacks_on_webpages: 1
  • 72. Weʼve aimed to... • easy to understanding • Can be extensible
  • 73. permissions: blog.your_permission: group: blog_admin label: Your New Permission order: 350 permitted_action: your_action: 1 your_other_action: 1
  • 75. Specify the role group. • blog_admin • auth_pub • sys_admin • blog_upload (only system level) • blog_comment • blog_design
  • 76. label The display name of the permission.
  • 77. order Ordering the permission in its role group
  • 78. permitted_action Hash to define a list of actions permitted for hte use who has this permission.
  • 79. inherit_from A list of inheritance origins for this permission. Defined by references to the list.
  • 84. Of course, you can add your menu by plugin.
  • 85. applications: cms: menus: tools:my_menu: label: Your Menu Label mode: your_mode order: 150 view: blog
  • 86. You can display your menu on any dashboard
  • 87. applications: cms: menus: tools:my_menu: label: Your Menu Label mode: your_mode order: 150 view: blog
  • 88. applications: cms: menus: tools:my_menu: label: Your Menu Label mode: your_mode order: 150 view: blog
  • 90. You can restrict your menu by permission.
  • 91. permissions: blog.your_permission: permitted_action: your_action: 1 applications: cms: menus: tools:my_menu: label: Your Menu Label mode: your_mode order: 150 view: blog permit_action: your_action
  • 92. If your plugin still supports MT4 and MT5
  • 93. menus: create:my_object:   condition: >   sub { MT->product_version < 5; }  entries:create:   condition: >   sub { MT->product_version >= 5; }
  • 101. CSS
  • 110. Thank you for listening.

Editor's Notes

  1. &amp;#x30A6;&amp;#x30A7;&amp;#x30D6;&amp;#x30B5;&amp;#x30A4;&amp;#x30C8;&amp;#x95A2;&amp;#x4FC2;&amp;#x3060;&amp;#x3051;&amp;#x3067;&amp;#x3053;&amp;#x308C;&amp;#x3060;&amp;#x3051;&amp;#x306E;&amp;#x30BF;&amp;#x30B0;&amp;#x304C;&amp;#x8FFD;&amp;#x52A0;&amp;#x3055;&amp;#x308C;&amp;#x3066;&amp;#x3044;&amp;#x307E;&amp;#x3059;&amp;#x304C;&amp;#x3001;&amp;#x30B5;&amp;#x30A4;&amp;#x30C8;&amp;#x3092;&amp;#x898B;&amp;#x3066;&amp;#x3044;&amp;#x305F;&amp;#x3060;&amp;#x3044;&amp;#x305F;&amp;#x65B9;&amp;#x304C;&amp;#x65E9;&amp;#x3044;&amp;#x304B;&amp;#x3068;&amp;#x601D;&amp;#x3044;&amp;#x307E;&amp;#x3059;
  2. &amp;#x5272;&amp;#x611B;&amp;#x3057;&amp;#x307E;&amp;#x3059;