Upload files to "ansico-some-plugin"
This commit is contained in:
parent
bc4caa4379
commit
02a3c109ea
4 changed files with 322 additions and 0 deletions
19
ansico-some-plugin/admin-script.js
Normal file
19
ansico-some-plugin/admin-script.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
jQuery(document).ready(function($){
|
||||
var mediaUploader;
|
||||
$('#ansico-upload-button').click(function(e) {
|
||||
e.preventDefault();
|
||||
if (mediaUploader) { mediaUploader.open(); return; }
|
||||
mediaUploader = wp.media({ title: 'Choose Avatar', button: { text: 'Set as Profile Picture' }, multiple: false });
|
||||
mediaUploader.on('select', function() {
|
||||
var attachment = mediaUploader.state().get('selection').first().toJSON();
|
||||
$('#ansico-avatar-url').val(attachment.url);
|
||||
$('#ansico-avatar-preview').attr('src', attachment.url).show();
|
||||
});
|
||||
mediaUploader.open();
|
||||
});
|
||||
$('#ansico-remove-button').click(function(e){
|
||||
e.preventDefault();
|
||||
$('#ansico-avatar-url').val('');
|
||||
$('#ansico-avatar-preview').hide().attr('src', '');
|
||||
});
|
||||
});
|
||||
176
ansico-some-plugin/ansico-some-plugin.php
Normal file
176
ansico-some-plugin/ansico-some-plugin.php
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
/**
|
||||
* Plugin Name: Ansico SoMe plugin
|
||||
* Description: Adds a custom avatar upload to user profiles and provides two blocks: an Author Profile and a SoMe Comment block.
|
||||
* Version: 1.0.0
|
||||
* Author: Ansico
|
||||
* Text Domain: ansico-some-plugin
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
add_action( 'show_user_profile', 'ansico_some_avatar_field' );
|
||||
add_action( 'edit_user_profile', 'ansico_some_avatar_field' );
|
||||
|
||||
function ansico_some_avatar_field( $user ) {
|
||||
$avatar_url = get_user_meta( $user->ID, 'ansico_avatar_url', true );
|
||||
?>
|
||||
<h3>Ansico Avatar</h3>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th><label for="ansico-avatar-url">Profile Picture</label></th>
|
||||
<td>
|
||||
<img id="ansico-avatar-preview" src="<?php echo esc_url( $avatar_url ); ?>" style="max-width: 150px; display: <?php echo $avatar_url ? 'block' : 'none'; ?>; border-radius: 50%; margin-bottom: 10px;" />
|
||||
<input type="hidden" name="ansico_avatar_url" id="ansico-avatar-url" value="<?php echo esc_url( $avatar_url ); ?>" class="regular-text" />
|
||||
<button type="button" class="button" id="ansico-upload-button">Upload / Select Image</button>
|
||||
<button type="button" class="button" id="ansico-remove-button" style="color: #a00;">Remove</button>
|
||||
<p class="description">Upload a custom profile picture. This will override Gravatar. If empty, Gravatar or standard logo will be used.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
}
|
||||
|
||||
add_action( 'personal_options_update', 'ansico_some_save_avatar' );
|
||||
add_action( 'edit_user_profile_update', 'ansico_some_save_avatar' );
|
||||
|
||||
function ansico_some_save_avatar( $user_id ) {
|
||||
if ( ! current_user_can( 'edit_user', $user_id ) ) { return false; }
|
||||
if ( isset( $_POST['ansico_avatar_url'] ) ) { update_user_meta( $user_id, 'ansico_avatar_url', esc_url_raw( $_POST['ansico_avatar_url'] ) ); }
|
||||
}
|
||||
|
||||
add_action( 'admin_enqueue_scripts', 'ansico_some_admin_scripts' );
|
||||
function ansico_some_admin_scripts( $hook ) {
|
||||
if ( $hook === 'profile.php' || $hook === 'user-edit.php' ) {
|
||||
wp_enqueue_media();
|
||||
wp_enqueue_script( 'ansico-some-admin-script', plugins_url( 'admin-script.js', __FILE__ ), array( 'jquery' ), '1.0.0', true );
|
||||
}
|
||||
}
|
||||
|
||||
add_filter( 'get_avatar_url', 'ansico_some_custom_avatar_url', 10, 3 );
|
||||
function ansico_some_custom_avatar_url( $url, $id_or_email, $args ) {
|
||||
$user_id = null;
|
||||
if ( is_numeric( $id_or_email ) ) { $user_id = $id_or_email; }
|
||||
elseif ( is_object( $id_or_email ) && isset( $id_or_email->user_id ) ) { $user_id = $id_or_email->user_id; }
|
||||
elseif ( is_string( $id_or_email ) ) { $user = get_user_by( 'email', $id_or_email ); if ( $user ) { $user_id = $user->ID; } }
|
||||
|
||||
if ( $user_id ) {
|
||||
$custom_avatar = get_user_meta( $user_id, 'ansico_avatar_url', true );
|
||||
if ( ! empty( $custom_avatar ) ) { return $custom_avatar; }
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
add_action( 'init', 'ansico_some_register_blocks' );
|
||||
function ansico_some_register_blocks() {
|
||||
wp_register_script(
|
||||
'ansico-some-blocks-script',
|
||||
plugins_url( 'block.js', __FILE__ ),
|
||||
array( 'wp-blocks', 'wp-element', 'wp-block-editor', 'wp-data', 'wp-components' ),
|
||||
'1.0.0'
|
||||
);
|
||||
|
||||
wp_register_style(
|
||||
'ansico-some-blocks-style',
|
||||
plugins_url( 'style.css', __FILE__ ),
|
||||
array(),
|
||||
'1.0.0'
|
||||
);
|
||||
|
||||
register_block_type( 'ansico/some-author', array(
|
||||
'editor_script' => 'ansico-some-blocks-script',
|
||||
'editor_style' => 'ansico-some-blocks-style',
|
||||
'style' => 'ansico-some-blocks-style',
|
||||
'render_callback' => 'ansico_some_render_author_block'
|
||||
) );
|
||||
|
||||
register_block_type( 'ansico/some-comment', array(
|
||||
'editor_script' => 'ansico-some-blocks-script',
|
||||
'editor_style' => 'ansico-some-blocks-style',
|
||||
'style' => 'ansico-some-blocks-style',
|
||||
'render_callback' => 'ansico_some_render_comment_block'
|
||||
) );
|
||||
}
|
||||
|
||||
function ansico_some_render_author_block( $attributes, $content, $block ) {
|
||||
$post_id = get_the_ID();
|
||||
$author_id = get_post_field( 'post_author', $post_id ) ?: get_current_user_id();
|
||||
$name = get_the_author_meta( 'display_name', $author_id );
|
||||
$bio = get_the_author_meta( 'description', $author_id );
|
||||
$avatar_url = get_avatar_url( $author_id, array( 'size' => 100 ) );
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div <?php echo get_block_wrapper_attributes( array( 'class' => 'ansico-compact-author' ) ); ?>>
|
||||
<div class="ansico-some-author-box">
|
||||
<img src="<?php echo esc_url( $avatar_url ); ?>" alt="Avatar" class="ansico-some-avatar" />
|
||||
<div class="ansico-some-info">
|
||||
<h3 class="ansico-some-name"><?php echo esc_html( $name ); ?></h3>
|
||||
<div class="ansico-some-bio"><?php echo wp_kses_post( wpautop( $bio ) ); ?></div>
|
||||
<div class="ansico-some-social-links"><?php echo $content; ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
function ansico_some_render_comment_block( $attributes ) {
|
||||
$text = isset( $attributes['text'] ) ? $attributes['text'] : '';
|
||||
$url = isset( $attributes['url'] ) ? $attributes['url'] : '';
|
||||
$time = isset( $attributes['time'] ) ? $attributes['time'] : '';
|
||||
|
||||
$author_id = get_post_field( 'post_author', get_the_ID() ) ?: get_current_user_id();
|
||||
$name = get_the_author_meta( 'display_name', $author_id );
|
||||
$avatar_url = get_avatar_url( $author_id, array( 'size' => 50 ) );
|
||||
|
||||
$domain = '';
|
||||
if ( ! empty( $url ) ) {
|
||||
$domain = parse_url( $url, PHP_URL_HOST );
|
||||
$domain = str_replace( 'www.', '', $domain );
|
||||
}
|
||||
|
||||
$time_display = $time;
|
||||
if ( ! empty( $time ) ) {
|
||||
$timestamp = strtotime( $time );
|
||||
if ( $timestamp ) {
|
||||
$date_format = get_option( 'date_format' );
|
||||
$time_format = get_option( 'time_format' );
|
||||
$formatted_time = wp_date( $time_format, $timestamp );
|
||||
$formatted_date = wp_date( $date_format, $timestamp );
|
||||
$time_display = $formatted_time . ' · ' . $formatted_date;
|
||||
}
|
||||
}
|
||||
|
||||
$source_label = __( 'Source:', 'ansico-some-plugin' );
|
||||
if ( $source_label === 'Source:' ) {
|
||||
$locale = get_locale();
|
||||
if ( strpos( $locale, 'da' ) === 0 ) { $source_label = 'Kilde:'; }
|
||||
elseif ( strpos( $locale, 'sv' ) === 0 ) { $source_label = 'Källa:'; }
|
||||
elseif ( strpos( $locale, 'no' ) === 0 || strpos( $locale, 'nb' ) === 0 || strpos( $locale, 'nn' ) === 0 ) { $source_label = 'Kilde:'; }
|
||||
elseif ( strpos( $locale, 'de' ) === 0 ) { $source_label = 'Quelle:'; }
|
||||
}
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div <?php echo get_block_wrapper_attributes( array( 'class' => 'ansico-some-tweet' ) ); ?>>
|
||||
<img src="<?php echo esc_url( $avatar_url ); ?>" alt="Avatar" class="ansico-tweet-avatar" />
|
||||
<div class="ansico-tweet-content">
|
||||
<div class="ansico-tweet-header">
|
||||
<span class="ansico-tweet-name"><?php echo esc_html( $name ); ?></span>
|
||||
<?php if ( $time_display ) : ?><span class="ansico-tweet-time"><?php echo wp_kses_post( $time_display ); ?></span><?php endif; ?>
|
||||
</div>
|
||||
<div class="ansico-tweet-text"><?php echo wp_kses_post( wpautop( $text ) ); ?></div>
|
||||
<?php if ( $domain ) : ?>
|
||||
<div class="ansico-tweet-footer">
|
||||
<?php echo esc_html( $source_label ); ?> <a href="<?php echo esc_url( $url ); ?>" target="_blank" rel="nofollow noreferrer"><?php echo esc_html( $domain ); ?></a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
?>
|
||||
73
ansico-some-plugin/block.js
Normal file
73
ansico-some-plugin/block.js
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
( function( blocks, element, blockEditor, data, components ) {
|
||||
var el = element.createElement;
|
||||
var useBlockProps = blockEditor.useBlockProps;
|
||||
var InnerBlocks = blockEditor.InnerBlocks;
|
||||
var TextControl = components.TextControl;
|
||||
var TextareaControl = components.TextareaControl;
|
||||
var useSelect = data.useSelect;
|
||||
var Spinner = components.Spinner;
|
||||
|
||||
blocks.registerBlockType( 'ansico/some-author', {
|
||||
title: 'Ansico Author Profile', icon: 'admin-users', category: 'widgets', supports: { html: false },
|
||||
edit: function( props ) {
|
||||
var blockProps = useBlockProps();
|
||||
var authorDetails = useSelect( function( select ) {
|
||||
var core = select( 'core' ); var editor = select( 'core/editor' );
|
||||
var authorId = editor ? editor.getCurrentPostAttribute( 'author' ) : null;
|
||||
if ( ! authorId ) { var currentUser = core.getCurrentUser(); authorId = currentUser ? currentUser.id : null; }
|
||||
return authorId ? core.getUser( authorId ) : null;
|
||||
}, [] );
|
||||
if ( ! authorDetails ) { return el( 'div', blockProps, el( Spinner ) ); }
|
||||
var avatarUrl = authorDetails.avatar_urls ? authorDetails.avatar_urls['96'] : '';
|
||||
|
||||
return el( 'div', blockProps,
|
||||
el( 'div', { className: 'ansico-some-author-box' },
|
||||
el( 'img', { src: avatarUrl, className: 'ansico-some-avatar', alt: 'Avatar' } ),
|
||||
el( 'div', { className: 'ansico-some-info' },
|
||||
el( 'h3', { className: 'ansico-some-name' }, authorDetails.name || 'Author Name' ),
|
||||
el( 'p', { className: 'ansico-some-bio' }, authorDetails.description || '...' ),
|
||||
el( 'div', { className: 'ansico-some-social-links' },
|
||||
el( InnerBlocks, { allowedBlocks: [ 'core/social-links' ], template: [ [ 'core/social-links', {}, [] ] ] } )
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
},
|
||||
save: function() { return el( 'div', useBlockProps.save(), el( InnerBlocks.Content ) ); }
|
||||
} );
|
||||
|
||||
blocks.registerBlockType( 'ansico/some-comment', {
|
||||
title: 'Ansico SoMe Comment', icon: 'format-status', category: 'widgets', supports: { html: false },
|
||||
attributes: { text: { type: 'string', default: '' }, url: { type: 'string', default: '' }, time: { type: 'string', default: '' } },
|
||||
edit: function( props ) {
|
||||
var attributes = props.attributes; var setAttributes = props.setAttributes; var blockProps = useBlockProps();
|
||||
var authorDetails = useSelect( function( select ) {
|
||||
var core = select( 'core' ); var editor = select( 'core/editor' );
|
||||
var authorId = editor ? editor.getCurrentPostAttribute( 'author' ) : null;
|
||||
if ( ! authorId ) { var currentUser = core.getCurrentUser(); authorId = currentUser ? currentUser.id : null; }
|
||||
return authorId ? core.getUser( authorId ) : null;
|
||||
}, [] );
|
||||
if ( ! authorDetails ) { return el( 'div', blockProps, el( Spinner ) ); }
|
||||
var avatarUrl = authorDetails.avatar_urls ? authorDetails.avatar_urls['48'] : '';
|
||||
|
||||
return el( 'div', blockProps,
|
||||
el( 'div', { className: 'ansico-some-tweet' },
|
||||
el( 'img', { src: avatarUrl, className: 'ansico-tweet-avatar', alt: 'Avatar' } ),
|
||||
el( 'div', { className: 'ansico-tweet-content' },
|
||||
el( 'div', { className: 'ansico-tweet-header' },
|
||||
el( 'span', { className: 'ansico-tweet-name' }, authorDetails.name || 'Author' ),
|
||||
el( 'span', { className: 'ansico-tweet-time' }, attributes.time || 'Time' )
|
||||
),
|
||||
el( 'div', { className: 'ansico-tweet-text' }, attributes.text || 'Message text...' )
|
||||
)
|
||||
),
|
||||
el( 'div', { style: { marginTop: '10px', borderTop: '1px solid #ddd', paddingTop: '10px' } },
|
||||
el( TextareaControl, { label: 'Comment Text', value: attributes.text, onChange: function( v ) { setAttributes( { text: v } ); } } ),
|
||||
el( TextControl, { label: 'Source URL', value: attributes.url, onChange: function( v ) { setAttributes( { url: v } ); } } ),
|
||||
el( TextControl, { label: 'Time (e.g. 2026-04-12 19:43)', value: attributes.time, onChange: function( v ) { setAttributes( { time: v } ); } } )
|
||||
)
|
||||
);
|
||||
},
|
||||
save: function() { return null; }
|
||||
} );
|
||||
} )( window.wp.blocks, window.wp.element, window.wp.blockEditor, window.wp.data, window.wp.components );
|
||||
54
ansico-some-plugin/style.css
Normal file
54
ansico-some-plugin/style.css
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/* Author Profile - Compact */
|
||||
.ansico-some-author-box { display: flex; gap: 20px; align-items: flex-start; background: #ffffff; padding: 15px; border-radius: 8px; border: 1px solid #eaeaea; }
|
||||
.ansico-some-avatar { width: 80px; height: 80px; min-width: 80px; border-radius: 50%; object-fit: cover; border: 2px solid #f0f0f0; margin: 0 !important; }
|
||||
.ansico-some-name { margin: 0 0 5px 0 !important; font-size: 18px; font-weight: 700; }
|
||||
.ansico-some-bio { margin: 0 0 10px 0 !important; font-size: 14px; color: #444; line-height: 1.5; }
|
||||
|
||||
/* SoMe Comment (Tweet Style) - FORCED LAYOUT */
|
||||
.ansico-some-tweet {
|
||||
display: flex !important;
|
||||
flex-direction: row !important;
|
||||
gap: 12px !important;
|
||||
align-items: flex-start !important;
|
||||
padding: 12px;
|
||||
border: 1px solid #eff3f4;
|
||||
border-radius: 12px;
|
||||
background: #ffffff;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
margin-bottom: 24px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.ansico-tweet-avatar {
|
||||
width: 48px !important;
|
||||
height: 48px !important;
|
||||
min-width: 48px !important;
|
||||
border-radius: 50% !important;
|
||||
object-fit: cover !important;
|
||||
margin: 0 !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.ansico-tweet-content {
|
||||
flex: 1 1 auto !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ansico-tweet-header {
|
||||
display: flex !important;
|
||||
align-items: baseline !important;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px !important;
|
||||
margin-bottom: 2px !important;
|
||||
}
|
||||
|
||||
.ansico-tweet-name { font-weight: 700 !important; color: #0f1419 !important; font-size: 15px !important; }
|
||||
.ansico-tweet-time { color: #536471 !important; font-size: 14px !important; }
|
||||
.ansico-tweet-text { font-size: 15px !important; line-height: 1.4 !important; color: #0f1419 !important; }
|
||||
.ansico-tweet-text p { margin-top: 0; }
|
||||
.ansico-tweet-footer { font-size: 11px !important; color: #536471 !important; margin-top: 8px !important; }
|
||||
.ansico-tweet-footer a { color: #1d9bf0 !important; text-decoration: none !important; }
|
||||
.ansico-tweet-footer a:hover { text-decoration: underline !important; }
|
||||
|
||||
.wp-block-ansico-some-author .ansico-some-bio { font-size: 14px; }
|
||||
.wp-block-ansico-some-author { margin-bottom: 24px; }
|
||||
Loading…
Reference in a new issue