Upload folder via GUI - includes
This commit is contained in:
38
includes/admin-columns.php
Normal file
38
includes/admin-columns.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
// Extra Spalten in der Admin-Übersicht
|
||||
add_filter( 'manage_mc_news_posts_columns', 'mcn_admin_columns' );
|
||||
function mcn_admin_columns( $cols ) {
|
||||
$new = [];
|
||||
foreach ( $cols as $key => $val ) {
|
||||
$new[ $key ] = $val;
|
||||
if ( $key === 'title' ) {
|
||||
$new['mcn_pinned'] = '📌 Angepinnt';
|
||||
$new['mcn_badge'] = '🏷️ Badge';
|
||||
$new['mcn_category'] = '📂 Kategorie';
|
||||
}
|
||||
}
|
||||
return $new;
|
||||
}
|
||||
|
||||
add_action( 'manage_mc_news_posts_custom_column', 'mcn_admin_column_content', 10, 2 );
|
||||
function mcn_admin_column_content( $col, $post_id ) {
|
||||
switch ( $col ) {
|
||||
case 'mcn_pinned':
|
||||
echo get_post_meta( $post_id, '_mcn_pinned', true ) ? '✅' : '—';
|
||||
break;
|
||||
case 'mcn_badge':
|
||||
$b = get_post_meta( $post_id, '_mcn_badge', true );
|
||||
echo $b ? '<strong>' . esc_html( $b ) . '</strong>' : '—';
|
||||
break;
|
||||
case 'mcn_category':
|
||||
$terms = get_the_terms( $post_id, 'mc_news_category' );
|
||||
if ( $terms ) {
|
||||
echo esc_html( implode( ', ', wp_list_pluck( $terms, 'name' ) ) );
|
||||
} else {
|
||||
echo '—';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
35
includes/assets.php
Normal file
35
includes/assets.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
add_action( 'wp_enqueue_scripts', 'mcn_enqueue_assets' );
|
||||
function mcn_enqueue_assets() {
|
||||
global $post;
|
||||
// Nur laden wenn Shortcode auf der Seite ist
|
||||
if ( is_a( $post, 'WP_Post' ) && (
|
||||
has_shortcode( $post->post_content, 'server_news' ) ||
|
||||
is_singular( 'mc_news' ) ||
|
||||
is_post_type_archive( 'mc_news' )
|
||||
) ) {
|
||||
wp_enqueue_style(
|
||||
'mcn-styles',
|
||||
MCN_URL . 'assets/css/mcn-style.css',
|
||||
[],
|
||||
MCN_VERSION
|
||||
);
|
||||
wp_enqueue_script(
|
||||
'mcn-scripts',
|
||||
MCN_URL . 'assets/js/mcn-script.js',
|
||||
[],
|
||||
MCN_VERSION,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'admin_enqueue_scripts', 'mcn_admin_assets' );
|
||||
function mcn_admin_assets( $hook ) {
|
||||
$screen = get_current_screen();
|
||||
if ( $screen && $screen->post_type === 'mc_news' ) {
|
||||
wp_enqueue_style( 'mcn-admin', MCN_URL . 'assets/css/mcn-admin.css', [], MCN_VERSION );
|
||||
}
|
||||
}
|
||||
60
includes/metaboxes.php
Normal file
60
includes/metaboxes.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
add_action( 'add_meta_boxes', 'mcn_add_metaboxes' );
|
||||
function mcn_add_metaboxes() {
|
||||
add_meta_box(
|
||||
'mcn_news_options',
|
||||
'⛏ News-Einstellungen',
|
||||
'mcn_render_metabox',
|
||||
'mc_news',
|
||||
'side',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
function mcn_render_metabox( $post ) {
|
||||
wp_nonce_field( 'mcn_save_meta', 'mcn_nonce' );
|
||||
|
||||
$pinned = get_post_meta( $post->ID, '_mcn_pinned', true );
|
||||
$badge = get_post_meta( $post->ID, '_mcn_badge', true );
|
||||
$server_ip = get_post_meta( $post->ID, '_mcn_server_ip', true );
|
||||
?>
|
||||
<p>
|
||||
<label><strong>📌 Angepinnt (immer oben)</strong></label><br>
|
||||
<input type="checkbox" name="mcn_pinned" value="1" <?php checked( $pinned, '1' ); ?>>
|
||||
<span>Diese News oben anzeigen</span>
|
||||
</p>
|
||||
<hr>
|
||||
<p>
|
||||
<label><strong>🏷️ Badge / Label</strong></label><br>
|
||||
<select name="mcn_badge" style="width:100%">
|
||||
<option value="">– Kein Badge –</option>
|
||||
<?php
|
||||
$badges = [ 'NEU', 'WICHTIG', 'HOT', 'BETA', 'LIVE', 'BALD' ];
|
||||
foreach ( $badges as $b ) {
|
||||
printf( '<option value="%s" %s>%s</option>', $b, selected( $badge, $b, false ), $b );
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</p>
|
||||
<hr>
|
||||
<p>
|
||||
<label><strong>🖥️ Server-IP (optional)</strong></label><br>
|
||||
<input type="text" name="mcn_server_ip" value="<?php echo esc_attr( $server_ip ); ?>"
|
||||
placeholder="play.deinserver.de" style="width:100%">
|
||||
<small>Wird in der News-Karte angezeigt</small>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
add_action( 'save_post_mc_news', 'mcn_save_metabox' );
|
||||
function mcn_save_metabox( $post_id ) {
|
||||
if ( ! isset( $_POST['mcn_nonce'] ) || ! wp_verify_nonce( $_POST['mcn_nonce'], 'mcn_save_meta' ) ) return;
|
||||
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
|
||||
if ( ! current_user_can( 'edit_post', $post_id ) ) return;
|
||||
|
||||
update_post_meta( $post_id, '_mcn_pinned', isset( $_POST['mcn_pinned'] ) ? '1' : '' );
|
||||
update_post_meta( $post_id, '_mcn_badge', sanitize_text_field( $_POST['mcn_badge'] ?? '' ) );
|
||||
update_post_meta( $post_id, '_mcn_server_ip', sanitize_text_field( $_POST['mcn_server_ip'] ?? '' ) );
|
||||
}
|
||||
31
includes/post-type.php
Normal file
31
includes/post-type.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
add_action( 'init', 'mcn_register_post_type' );
|
||||
function mcn_register_post_type() {
|
||||
$labels = [
|
||||
'name' => 'Server News',
|
||||
'singular_name' => 'News',
|
||||
'add_new' => 'News hinzufügen',
|
||||
'add_new_item' => 'Neue News erstellen',
|
||||
'edit_item' => 'News bearbeiten',
|
||||
'new_item' => 'Neue News',
|
||||
'view_item' => 'News ansehen',
|
||||
'search_items' => 'News suchen',
|
||||
'not_found' => 'Keine News gefunden',
|
||||
'not_found_in_trash' => 'Keine News im Papierkorb',
|
||||
'menu_name' => '⛏ Server News',
|
||||
];
|
||||
|
||||
register_post_type( 'mc_news', [
|
||||
'labels' => $labels,
|
||||
'public' => true,
|
||||
'show_in_menu' => true,
|
||||
'menu_icon' => 'dashicons-megaphone',
|
||||
'menu_position' => 5,
|
||||
'supports' => [ 'title', 'editor', 'thumbnail', 'excerpt', 'author' ],
|
||||
'has_archive' => true,
|
||||
'rewrite' => [ 'slug' => 'server-news' ],
|
||||
'show_in_rest' => true,
|
||||
] );
|
||||
}
|
||||
140
includes/shortcode.php
Normal file
140
includes/shortcode.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
add_shortcode( 'server_news', 'mcn_render_shortcode' );
|
||||
|
||||
function mcn_render_shortcode( $atts ) {
|
||||
$atts = shortcode_atts( [
|
||||
'anzahl' => 10,
|
||||
'kategorie' => '',
|
||||
'layout' => 'grid', // grid | list
|
||||
'badge' => '',
|
||||
], $atts, 'server_news' );
|
||||
|
||||
$args = [
|
||||
'post_type' => 'mc_news',
|
||||
'posts_per_page' => intval( $atts['anzahl'] ),
|
||||
'post_status' => 'publish',
|
||||
'meta_query' => [],
|
||||
'tax_query' => [],
|
||||
];
|
||||
|
||||
// Kategorie-Filter
|
||||
if ( ! empty( $atts['kategorie'] ) ) {
|
||||
$args['tax_query'][] = [
|
||||
'taxonomy' => 'mc_news_category',
|
||||
'field' => 'slug',
|
||||
'terms' => array_map( 'trim', explode( ',', $atts['kategorie'] ) ),
|
||||
];
|
||||
}
|
||||
|
||||
// Angepinnte zuerst
|
||||
$pinned_args = $args;
|
||||
$pinned_args['meta_query'][] = [ 'key' => '_mcn_pinned', 'value' => '1' ];
|
||||
$pinned_query = new WP_Query( $pinned_args );
|
||||
|
||||
$normal_args = $args;
|
||||
$normal_args['meta_query'][] = [
|
||||
'relation' => 'OR',
|
||||
[ 'key' => '_mcn_pinned', 'compare' => 'NOT EXISTS' ],
|
||||
[ 'key' => '_mcn_pinned', 'value' => '', 'compare' => '=' ],
|
||||
];
|
||||
$normal_query = new WP_Query( $normal_args );
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="mcn-wrapper mcn-layout-<?php echo esc_attr( $atts['layout'] ); ?>">
|
||||
|
||||
<?php // ---- Filter-Bar ---- ?>
|
||||
<div class="mcn-filterbar">
|
||||
<button class="mcn-filter-btn active" data-filter="all">📋 Alle</button>
|
||||
<?php
|
||||
$cats = get_terms( [ 'taxonomy' => 'mc_news_category', 'hide_empty' => true ] );
|
||||
foreach ( $cats as $cat ) {
|
||||
$icon = ! empty( $cat->description ) ? $cat->description . ' ' : '';
|
||||
printf(
|
||||
'<button class="mcn-filter-btn" data-filter="%s">%s%s</button>',
|
||||
esc_attr( $cat->slug ),
|
||||
$icon,
|
||||
esc_html( $cat->name )
|
||||
);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="mcn-grid">
|
||||
<?php
|
||||
// Angepinnte zuerst
|
||||
foreach ( [ $pinned_query, $normal_query ] as $query ) {
|
||||
while ( $query->have_posts() ) {
|
||||
$query->the_post();
|
||||
$post_id = get_the_ID();
|
||||
$pinned = get_post_meta( $post_id, '_mcn_pinned', true );
|
||||
$badge = get_post_meta( $post_id, '_mcn_badge', true );
|
||||
$server_ip = get_post_meta( $post_id, '_mcn_server_ip', true );
|
||||
$cats = get_the_terms( $post_id, 'mc_news_category' );
|
||||
$cat_slugs = $cats ? implode( ' ', wp_list_pluck( $cats, 'slug' ) ) : '';
|
||||
$cat_name = $cats ? $cats[0]->name : '';
|
||||
$cat_icon = $cats ? $cats[0]->description : '📰';
|
||||
?>
|
||||
<article class="mcn-card <?php echo $pinned ? 'mcn-pinned' : ''; ?>"
|
||||
data-category="<?php echo esc_attr( $cat_slugs ); ?>">
|
||||
|
||||
<?php if ( $pinned ) : ?>
|
||||
<div class="mcn-pin-label">📌 Angepinnt</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( $badge ) : ?>
|
||||
<div class="mcn-badge mcn-badge-<?php echo esc_attr( strtolower( $badge ) ); ?>"><?php echo esc_html( $badge ); ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( has_post_thumbnail() ) : ?>
|
||||
<div class="mcn-card-image">
|
||||
<a href="<?php the_permalink(); ?>">
|
||||
<?php the_post_thumbnail( 'medium_large' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="mcn-card-body">
|
||||
<?php if ( $cat_name ) : ?>
|
||||
<span class="mcn-cat-tag"><?php echo $cat_icon . ' ' . esc_html( $cat_name ); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<h2 class="mcn-card-title">
|
||||
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
|
||||
</h2>
|
||||
|
||||
<div class="mcn-card-meta">
|
||||
<span class="mcn-date">📅 <?php echo get_the_date( 'd.m.Y' ); ?></span>
|
||||
<span class="mcn-author">✍️ <?php the_author(); ?></span>
|
||||
</div>
|
||||
|
||||
<div class="mcn-card-excerpt">
|
||||
<?php echo wp_trim_words( get_the_excerpt(), 20, '…' ); ?>
|
||||
</div>
|
||||
|
||||
<?php if ( $server_ip ) : ?>
|
||||
<div class="mcn-server-ip">
|
||||
🖥️ <span><?php echo esc_html( $server_ip ); ?></span>
|
||||
<button class="mcn-copy-btn" data-ip="<?php echo esc_attr( $server_ip ); ?>">Kopieren</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<a href="<?php the_permalink(); ?>" class="mcn-read-more">Weiterlesen →</a>
|
||||
</div>
|
||||
</article>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
wp_reset_postdata();
|
||||
?>
|
||||
</div><!-- .mcn-grid -->
|
||||
|
||||
<div class="mcn-empty" style="display:none">
|
||||
<p>😔 Keine News in dieser Kategorie gefunden.</p>
|
||||
</div>
|
||||
</div><!-- .mcn-wrapper -->
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
50
includes/taxonomies.php
Normal file
50
includes/taxonomies.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
add_action( 'init', 'msn_register_taxonomies' );
|
||||
function msn_register_taxonomies() {
|
||||
|
||||
/* --- Kategorie (Update, Event, Wartung …) --- */
|
||||
register_taxonomy( 'msn_category', 'msn_news', [
|
||||
'labels' => [
|
||||
'name' => 'News-Kategorien',
|
||||
'singular_name' => 'Kategorie',
|
||||
'add_new_item' => 'Neue Kategorie',
|
||||
'edit_item' => 'Kategorie bearbeiten',
|
||||
'search_items' => 'Kategorien suchen',
|
||||
'not_found' => 'Keine Kategorien gefunden',
|
||||
'menu_name' => 'Kategorien',
|
||||
],
|
||||
'hierarchical' => true,
|
||||
'show_in_menu' => true,
|
||||
'show_in_rest' => true,
|
||||
'rewrite' => [ 'slug' => 'news-kategorie' ],
|
||||
] );
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------
|
||||
Standard-Kategorien beim ersten Aktivieren anlegen
|
||||
------------------------------------------------------- */
|
||||
add_action( 'init', 'msn_insert_default_categories', 20 );
|
||||
function msn_insert_default_categories() {
|
||||
if ( get_option( 'msn_defaults_created' ) ) return;
|
||||
|
||||
$defaults = [
|
||||
[ 'name' => '🔧 Update', 'slug' => 'update', 'description' => 'Server-Updates & Patches' ],
|
||||
[ 'name' => '🎉 Event', 'slug' => 'event', 'description' => 'Community-Events & Aktionen' ],
|
||||
[ 'name' => '⚠️ Wartung', 'slug' => 'wartung', 'description' => 'Geplante Wartungsarbeiten' ],
|
||||
[ 'name' => '📢 Ankündigung', 'slug' => 'ankundigung','description' => 'Wichtige Ankündigungen' ],
|
||||
[ 'name' => '🐛 Bugfix', 'slug' => 'bugfix', 'description' => 'Fehlerbehebungen' ],
|
||||
];
|
||||
|
||||
foreach ( $defaults as $cat ) {
|
||||
if ( ! term_exists( $cat['slug'], 'msn_category' ) ) {
|
||||
wp_insert_term( $cat['name'], 'msn_category', [
|
||||
'slug' => $cat['slug'],
|
||||
'description' => $cat['description'],
|
||||
] );
|
||||
}
|
||||
}
|
||||
|
||||
update_option( 'msn_defaults_created', true );
|
||||
}
|
||||
45
includes/taxonomy.php
Normal file
45
includes/taxonomy.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
add_action( 'init', 'mcn_register_taxonomy' );
|
||||
function mcn_register_taxonomy() {
|
||||
$labels = [
|
||||
'name' => 'Kategorien',
|
||||
'singular_name' => 'Kategorie',
|
||||
'search_items' => 'Kategorien suchen',
|
||||
'all_items' => 'Alle Kategorien',
|
||||
'parent_item' => 'Übergeordnete Kategorie',
|
||||
'edit_item' => 'Kategorie bearbeiten',
|
||||
'update_item' => 'Kategorie aktualisieren',
|
||||
'add_new_item' => 'Neue Kategorie',
|
||||
'new_item_name' => 'Name der neuen Kategorie',
|
||||
'menu_name' => 'Kategorien',
|
||||
];
|
||||
|
||||
register_taxonomy( 'mc_news_category', 'mc_news', [
|
||||
'labels' => $labels,
|
||||
'hierarchical' => true,
|
||||
'public' => true,
|
||||
'show_admin_column' => true,
|
||||
'rewrite' => [ 'slug' => 'news-kategorie' ],
|
||||
'show_in_rest' => true,
|
||||
] );
|
||||
|
||||
// Standard-Kategorien beim ersten Aufruf anlegen
|
||||
add_action( 'init', function() {
|
||||
$defaults = [
|
||||
'Update' => '🔄',
|
||||
'Event' => '🎉',
|
||||
'Wartung' => '🔧',
|
||||
'Wichtig' => '⚠️',
|
||||
'Community' => '👥',
|
||||
];
|
||||
foreach ( $defaults as $name => $icon ) {
|
||||
if ( ! term_exists( $name, 'mc_news_category' ) ) {
|
||||
wp_insert_term( $name, 'mc_news_category', [
|
||||
'description' => $icon,
|
||||
] );
|
||||
}
|
||||
}
|
||||
}, 20 );
|
||||
}
|
||||
78
includes/widget.php
Normal file
78
includes/widget.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) exit;
|
||||
|
||||
add_action( 'widgets_init', function() {
|
||||
register_widget( 'MCN_Latest_News_Widget' );
|
||||
} );
|
||||
|
||||
class MCN_Latest_News_Widget extends WP_Widget {
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct( 'mcn_latest_news', '⛏ Minecraft Server News', [
|
||||
'description' => 'Zeigt die neuesten Server-News in der Sidebar.',
|
||||
] );
|
||||
}
|
||||
|
||||
public function widget( $args, $instance ) {
|
||||
$title = apply_filters( 'widget_title', $instance['title'] ?? 'Server News' );
|
||||
$anzahl = intval( $instance['anzahl'] ?? 3 );
|
||||
|
||||
echo $args['before_widget'];
|
||||
if ( $title ) echo $args['before_title'] . $title . $args['after_title'];
|
||||
|
||||
$query = new WP_Query( [
|
||||
'post_type' => 'mc_news',
|
||||
'posts_per_page' => $anzahl,
|
||||
'post_status' => 'publish',
|
||||
] );
|
||||
|
||||
if ( $query->have_posts() ) {
|
||||
echo '<ul class="mcn-widget-list">';
|
||||
while ( $query->have_posts() ) {
|
||||
$query->the_post();
|
||||
$cats = get_the_terms( get_the_ID(), 'mc_news_category' );
|
||||
$icon = ( $cats && ! empty( $cats[0]->description ) ) ? $cats[0]->description . ' ' : '📰 ';
|
||||
printf(
|
||||
'<li class="mcn-widget-item"><a href="%s">%s%s</a><span class="mcn-widget-date">%s</span></li>',
|
||||
get_permalink(),
|
||||
$icon,
|
||||
get_the_title(),
|
||||
get_the_date( 'd.m.Y' )
|
||||
);
|
||||
}
|
||||
echo '</ul>';
|
||||
wp_reset_postdata();
|
||||
} else {
|
||||
echo '<p>Noch keine News vorhanden.</p>';
|
||||
}
|
||||
|
||||
echo $args['after_widget'];
|
||||
}
|
||||
|
||||
public function form( $instance ) {
|
||||
$title = $instance['title'] ?? 'Server News';
|
||||
$anzahl = $instance['anzahl'] ?? 3;
|
||||
?>
|
||||
<p>
|
||||
<label for="<?php echo $this->get_field_id( 'title' ); ?>">Titel:</label>
|
||||
<input class="widefat" type="text" id="<?php echo $this->get_field_id( 'title' ); ?>"
|
||||
name="<?php echo $this->get_field_name( 'title' ); ?>"
|
||||
value="<?php echo esc_attr( $title ); ?>">
|
||||
</p>
|
||||
<p>
|
||||
<label for="<?php echo $this->get_field_id( 'anzahl' ); ?>">Anzahl News:</label>
|
||||
<input class="widefat" type="number" min="1" max="10"
|
||||
id="<?php echo $this->get_field_id( 'anzahl' ); ?>"
|
||||
name="<?php echo $this->get_field_name( 'anzahl' ); ?>"
|
||||
value="<?php echo esc_attr( $anzahl ); ?>">
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function update( $new, $old ) {
|
||||
return [
|
||||
'title' => sanitize_text_field( $new['title'] ),
|
||||
'anzahl' => intval( $new['anzahl'] ),
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user