Movable Type 7コンテンツデータのコピペ

らら
らら

はじめに

なんとなくほしくて作成してみた。

コンテンツデータを1件だけ公開サイトへアップしたいとかあると

コンテンツデータの1つ1つの項目をコピペとかになったり不便なのでつくってみようかと・・

ウェブページとかなら、がっと・・コピペでよいですが・・・

つくってみたもの・・

下記の感じ

コンテンツデータの新規・修正画面にボタンが付きます・・

Movable Type 7コンテンツデータのコピペ

使い方

コンテンツデータでコピーしたいもので編集画面へ移ります。

該当のコンテンツデータをコピーをクリックします。

メモ帳でペーストするとこんな感じです。

data_label=1234&content-field-xx=&content-field-xx=&content-field-xx=

こちらを保存して後からも使用できます。

別のサイトの新規作成で

該当のコンテンツデータをペーストをクリックします。

制限事項

コンテンツタイプで同じ作成になっていないとコピーできません。内部で持っているIDとか

html inputタグのname名が一致しないとコピーできません。content-field-xxの部分

クリップボードAPIを利用しているのでSSL配下でないと動作しないかもしれません。

input tag select radio textareaは確認にしていますが・・その他は確認していません。

仕組み

JQueryのserializeをつかって、クリップボードへ保存。保存したものをdeserializeしているだけです。

edit-content-type-data-formとか直指定しているのでMT側で変更されると動かないです。

jq_js_includeでhtmlファイルだけで作成もできるけど。全画面にタグが入るのでプラグインでコンテンツデータのみにしています。。

ソース


│  config.yaml
│  
└─lib
    └─CopyPasteContentData
        │  L10N.pm
        │  Transformer.pm
        │  
        └─L10N
                ja.pm

config.yamlの内容


id: CopyPasteContentData
key: CopyPasteContentData
name: Copy & Paste Content Data
description: 
version: 0.01
author_name: 
plugin_link:
l10n_class: CopyPasteContentData::L10N
callbacks:
  template_param.edit_content_data: $CopyPasteContentData::CopyPasteContentData::Transformer::template_param_edit_content_data

L10N.pmの内容


package CopyPasteContentData::L10N;
use strict;
use warnings;
use parent 'MT::Plugin::L10N';
1;

ja.pmの内容


package CopyPasteContentData::L10N::ja;
use strict;
use warnings;
use utf8;
use parent 'CopyPasteContentData::L10N';
our %Lexicon = (
    'TThis plugin provides a Copy & Paste content data.' =>
        'コンテンツデータをコピーして、同一のコンテンツデータにペーストします。',
    'Copy this Content Data' => '該当のコンテンツをコピー',
    'Paste this Content Data' => '該当のコンテンツをペースト',
    'Copy & Paste this Content Data' => '該当のコンテンツをコピペする',
);

Transformer.pmの内容


package CopyPasteContentData::Transformer;
use strict;
use warnings;
use JSON ();
use MT;
use MT::ContentStatus;
sub template_param_edit_content_data {
    my ( $cb, $app, $param, $tmpl ) = @_;
    my $plugin = _get_plugin();
    my $widget = $tmpl->createElement(
        'app:widget',
        {   id    => 'copy-and-paste-content-data-widget',
            label => $plugin->translate('Copy & Paste this Content Data'),
        }
    );
    $widget->appendChild(
        $tmpl->createTextNode(
            '<div style="margin-left: auto; margin-right: auto;">'
            .'<button type="button" id="copy-content-data" name="copy-content-data" class="action button btn btn-default" style="width: 100%;">'
            . $plugin->translate('Copy this Content Data')
            .'</button>'
            .'<button type="button" id="paste-content-data" name="paste-content-data" class="action button btn btn-default" style="width: 100%;">'
            . $plugin->translate('Paste this Content Data')
            .'</button>'
            .'</div>'
        )
    );
    $tmpl->insertBefore( $widget, $tmpl->getElementById('entry-publishing-widget') );
    # hook jq_js_include
    $param->{jq_js_include} ||= '';
    $param->{jq_js_include} .= <<SCRIPT;
    jQuery('#copy-content-data').click(function() {
		event.preventDefault();
		navigator.clipboard.writeText(jQuery('form#edit-content-type-data-form input[name=data_label],input[name^=content-field-]').serialize());
    });
    jQuery('#paste-content-data').click(function() {
		navigator.clipboard.readText()
		.then((text) => {
			jQuery('form#edit-content-type-data-form').deserialize(text);
		})
		.catch(err => {
		});
    });
  jQuery.fn.deserialize = function(s, options){
    var opts = jQuery.extend({}, jQuery.fn.deserialize.defaults, options);
    return this.each(function(){
      var self = this;
      var parts = s.replace(/^\\?/, '').split('&');
      var data = {};
      jQuery.each(parts, function(i, part){
        var pair = part.split('=');
        var name = decodeURIComponent(pair[0]);
        var value = decodeURIComponent(pair[1]);
        if (opts.filter && !opts.filter.call(self, name, value)) return;
        if (!(name in data)) data[name] = [];
        data[name].push(value);
      });
      jQuery.each(data, function(name, values){
        jQuery('[name="' + name + '"]:input', self).val(values);
      });
    });
  };
  jQuery.fn.deserialize.defaults = {
    filter: function(name, value){
      if (jQuery('[name="' + name + '"]:input', this).is(':submit')) return false;
      return true;
    }
  };
SCRIPT
}
sub _get_plugin {
    MT->component('CopyPasteContentData');
}
1;

jquery.deserialize.jsは下記から

https://gist.github.com/nissuk/835256

改修してみた

下記の部分

コンテンツタイプで同じ作成になっていないとコピーできません。内部で持っているIDとか

html inputタグのname名が一致しないとコピーできません。content-field-xxの部分

対処

コピー先のname=を先に取得して取得した順番で単純にname=の差し替えをした。

単純に上から順に差し替えただけなので不具合がでるかもしれません。

radioなど、初期選択されていないと。飛びぬけしたりします。

コピー先のnameと一致した場合は、素直に変更ぜす。コピー元のままコピーしています。

あと。拝借してきているjqueryライブラリーがperlのヒアドキュメントで$化けして面倒だったので外部にしました。

content-field-01 ->content-field-21

content-field-02 ->content-field-22

content-field-03 ->content-field-23

content-field-04 ->content-field-24

content-field-05 ->content-field-25

content-field-06 ->content-field-26


└─mt-static
    └─plugins CopyPasteContentData
        └─CopyPasteContentData
                jquery.deserialize.js

改修で変更したjquery.deserialize.jsは下記から

https://github.com/kflorence/jquery-deserialize/

Transformer.pmの変更内容


package CopyPasteContentData::Transformer;
use strict;
use warnings;
use JSON ();
use MT;
use MT::ContentStatus;
sub template_param_edit_content_data {
    my ( $cb, $app, $param, $tmpl ) = @_;
    my $plugin = _get_plugin();
    my $widget = $tmpl->createElement(
        'app:widget',
        {   id    => 'copy-and-paste-content-data-widget',
            label => $plugin->translate('Copy & Paste this Content Data'),
        }
    );
    $widget->appendChild(
        $tmpl->createTextNode(
            '<div style="margin-left: auto; margin-right: auto;">'
            .'<button type="button" id="copy-content-data" name="copy-content-data" class="action button btn btn-default" style="width: 100%;">'
            . $plugin->translate('Copy this Content Data')
            .'</button>'
            .'<button type="button" id="paste-content-data" name="paste-content-data" class="action button btn btn-default" style="width: 100%;">'
            . $plugin->translate('Paste this Content Data')
            .'</button>'
            .'</div>'
        )
    );
    $tmpl->insertBefore( $widget, $tmpl->getElementById('entry-publishing-widget') );
    # hook jq_js_include
	my $static_uri = MT->static_path;
    $param->{jq_js_include} ||= '';
    $param->{jq_js_include} .= <<SCRIPT;
    jQuery('#copy-content-data').click(function() {
		event.preventDefault();
		var clpdt =jQuery('form#edit-content-type-data-form input[name=data_label],input[name^=content-field-]').serialize();
		navigator.clipboard.writeText(clpdt);
    });
    jQuery('#paste-content-data').click(function() {
		navigator.clipboard.readText()
		.then((text) => {
			var newdt = jQuery('form#edit-content-type-data-form input[name=data_label],input[name^=content-field-]').serialize();
			text=chgnameForm(newdt,text);
			jQuery('form#edit-content-type-data-form').deserialize(text);
		})
		.catch(err => {
		});
    });
	function chgnameForm(nowform,saveform) {
		var strnow = nowform.split('&');
		var strsave = saveform.split('&');
		var len = strnow.length;
		var cmplen = 0;
		var newform="";
		for (let i = 0; i < strnow.length; i++) {
			now_array = strnow[i].split("=");
			save_array = strsave[i].split("=");
			if(now_array[0] == save_array[0]) {
				newform = newform + save_array[0] + '=' + save_array[1] + '&';
				cmplen ++;
			} else {
				newform = newform + now_array[0] + '=' + save_array[1] + '&';
			}
		}
		if(cmplen == len) {
			return saveform;
		} else {
			return newform.replace(\/&\$\/,"");
		}
	}
SCRIPT
    $param->{js_include} ||= '';
    $param->{js_include} .= <<SCRIPT;
<script type="text/javascript" src="${static_uri}plugins/CopyPasteContentData/jquery.deserialize.js"></script>
SCRIPT
}
sub _get_plugin {
    MT->component('CopyPasteContentData');
}
1;

さいごに

とくに著作とか・・いいませんよ。。保証もないですし・・

完全にテストしていません。

movable type8のプレビューでましたね。なんか。個人的には便利って思うところが...なかった・・・

個別のインポート・エクスポートほしいです。。まじで。。記事のカテゴリだけとか、コンテンツタイプ、コンテンツデータ、記事、ウェブページ毎で

コンテンツデータの検索強化ってあったので期待してましたが、管理画面側なんですね・・

movable typeコマンドラインのツール類あるちゃぁ。。あるんですが・・プラグインとかでWEBでポンってしてほしいです。なんとかpressみたいに・・

基本外部プラグインって・・どのソフトもバージョンアップで必ず・・支障となるので・・・・標準機能にしてほしいです。。

関連記事