wordpress
WordPressで投稿に際してのメディアモーダルの表示数変更
最終更新日: 2025年5月10日
管理しているサイトだが、1000以上のメディア(ほぼimg)があるが、ライブラリ画像を使いまわす際などに画像を探すのに手間がかかる。
80ずつ表示されていて更に画像を表示させる際は、クリックとローディング待ち時間を要すのだが、これが管理者としては甚だ面倒。
小さなことだが、この80という表示数をカスタムするコード。
add_filter('ajax_query_attachments_args', function($query) {
if (isset($query['post_type']) && $query['post_type'] === 'attachment') {
$query['posts_per_page'] = 100; // 表示件数を100件に設定
$query['no_found_rows'] = false; // ページネーションを有効化
$query['orderby'] = 'date'; // 並び順を投稿日時に設定
$query['order'] = 'DESC'; // 降順で表示 } // デバッグ用ログを出力
error_log('Modified query for attachments: ' . print_r($query, true));
return $query;
});
これをfunction.phpに追記すればテーマにもよるが200ずつ表示になる。
200を任意の数値にすれば表示数を変えられるが、大きい数字にしてローディング等がどうなるか検証をしていないことから節度を持った使い方がベターかも。
上記コードではページネーションの初期値80がそのまま残るのでメディアすべてが表示されなくなる
ってことで修正。
PNの区切り数値を表示数と整合させる必要があったので、AI使って修正。
ついでに設定画面option-generalで数値入力して変えられるようにした。
add_action('admin_init', function() {
// 設定フィールドの登録
register_setting('general', 'media_posts_per_page', 'absint');
// カスタムフィールドを追加
add_settings_field(
'media_posts_per_page',
'Media Modal Posts per Page',
function($args) {
$value = get_option('media_posts_per_page', 80);
?>
<input type="number" id="media_posts_per_page" name="media_posts_per_page" value="<?php echo esc_attr($value); ?>" min="1" class="small-text" />
<p class="description">初期値: 80.</p>
<?php
},
'general',
'default',
array('label_for' => 'media_posts_per_page')
);
error_log('admin_init hook fired for media_posts_per_page'); // デバッグログ
});
add_filter('ajax_query_attachments_args', function($query) {
if (isset($query['post_type']) && $query['post_type'] === 'attachment') {
$desired_posts_per_page = get_option('media_posts_per_page', 80);
$query['posts_per_page'] = absint($desired_posts_per_page);
$query['no_found_rows'] = false;
$query['orderby'] = 'date';
$query['order'] = 'DESC';
$paged = 1;
if (isset($_REQUEST['paged'])) {
$paged = absint($_REQUEST['paged']);
} elseif (isset($_REQUEST['query']['paged'])) {
$paged = absint($_REQUEST['query']['paged']);
}
$query['paged'] = max(1, $paged);
error_log('AJAX request data: ' . print_r($_REQUEST, true));
error_log('Modified query for attachments: ' . print_r($query, true));
}
return $query;
}, 999);
// クライアント側のposts_per_pageを完全同期
add_action('admin_footer', function() {
$posts_per_page = get_option('media_posts_per_page', 80);
?>
<script>
jQuery(document).ready(function($) {
// メディアクエリの初期化時にposts_per_pageを設定
var originalQuery = wp.media.query;
wp.media.query = function(props) {
props = $.extend({
posts_per_page: <?php echo esc_js($posts_per_page); ?>,
orderby: 'date',
order: 'DESC'
}, props);
console.log('Media query initialized. Posts per page: ', props.posts_per_page);
return originalQuery(props);
};
// メディアモーダル開く時に状態をリセット
wp.media.on('open', function() {
var frame = wp.media.frame;
if (frame && frame.content.get() && frame.content.get().collection) {
var collection = frame.content.get().collection;
collection.args.posts_per_page = <?php echo esc_js($posts_per_page); ?>;
collection.args.queryVars.posts_per_page = <?php echo esc_js($posts_per_page); ?>;
collection.state().set('total', 0);
collection.state().set('current_page', 1);
console.log('Media frame opened. Posts per page: ', collection.args.posts_per_page);
console.log('QueryVars posts per page: ', collection.args.queryVars.posts_per_page);
console.log('Collection state reset: ', {
total: collection.state().get('total'),
current_page: collection.state().get('current_page')
});
}
});
// フェッチ時にposts_per_pageを強制設定
wp.media.model.Attachments = wp.media.model.Attachments.extend({
sync: function(method, model, options) {
this.args.posts_per_page = <?php echo esc_js($posts_per_page); ?>;
this.args.queryVars.posts_per_page = <?php echo esc_js($posts_per_page); ?>;
options.data.posts_per_page = <?php echo esc_js($posts_per_page); ?>;
options.data.query = Object.assign({}, options.data.query || {}, {
posts_per_page: <?php echo esc_js($posts_per_page); ?>,
paged: this.args.paged || 1,
orderby: 'date',
order: 'DESC'
});
console.log('Fetching page: ', this.args.paged);
console.log('Request data: ', options.data);
return wp.media.model.Attachments.__super__.sync.apply(this, arguments).done(function(response) {
console.log('Fetch success. Found posts: ', response.found_posts, 'Max pages: ', response.max_num_pages);
console.log('Data length: ', response.data.length);
console.log('Collection hasMore after fetch: ', model.hasMore());
console.log('Collection state: ', {
total: model.state().get('total'),
current_page: model.state().get('current_page'),
total_pages: Math.ceil(model.state().get('total') / <?php echo esc_js($posts_per_page); ?>)
});
// コレクション状態を更新
if (response.found_posts) {
model.state().set('total', response.found_posts);
model.state().set('current_page', options.data.paged);
}
}).fail(function(response) {
console.error('Fetch error: ', response);
});
},
hasMore: function() {
var total = this.state().get('total');
var current_page = this.state().get('current_page') || 1;
var total_pages = Math.ceil(total / <?php echo esc_js($posts_per_page); ?>);
console.log('hasMore check: ', {
total: total,
current_page: current_page,
total_pages: total_pages,
hasMore: current_page < total_pages
});
return current_page < total_pages;
}
});
// ボタンクリック時のデバッグ
$(document).on('click', '.attachments-browser .load-more', function() {
var collection = wp.media.frame.content.get().collection;
console.log('Load more button clicked. Current page: ', collection.args.paged);
console.log('Button visible: ', $(this).is(':visible'));
console.log('Button disabled: ', $(this).prop('disabled'));
console.log('Collection hasMore: ', collection.hasMore());
console.log('Collection state: ', {
total: collection.state().get('total'),
current_page: collection.state().get('current_page'),
total_pages: Math.ceil(collection.state().get('total') / <?php echo esc_js($posts_per_page); ?>)
});
});
});
</script>
<?php
});
もちろんテーマによるが、写真枚数があって使いまわしなどする場合は便利かも。
逆に80から減らすのもOK。