array(
'name' => __('All Cards', 'aj-card-element'),
'singular_name' => __('Card', 'aj-card-element'),
'add_new' => __('Add New Card', 'aj-card-element'),
'add_new_item' => __('Add New Card', 'aj-card-element'),
),
'public' => true,
'has_archive' => false,
'supports' => array('title', 'thumbnail'),
'show_in_menu' => 'ajcelt-main-menu',
'menu_icon' => 'dashicons-format-status',
));
}
add_action('init', 'ajcelt_register_tool_cpt');
// Register Groups CPT
function ajcelt_register_group_post_type() {
register_post_type('ajcelt_group', array(
'labels' => array(
'name' => 'CardGroups',
'singular_name' => 'Group',
'add_new' => 'Add New Group',
'add_new_item' => 'Add New Group',
'edit_item' => 'Edit Group',
'new_item' => 'New Group',
'view_item' => 'View Group',
'search_items' => 'Search Groups',
'not_found' => 'No groups found',
'not_found_in_trash' => 'No groups found in trash',
'all_items' => 'All Groups',
'menu_name' => 'Groups',
),
'public' => true,
'has_archive' => true,
'show_in_rest' => true,
'supports' => array('title'),
'show_ui' => true,
'show_in_menu' => 'ajcelt-main-menu',
));
}
add_action('init', 'ajcelt_register_group_post_type');
// Register Top-Level Menu (AJ Card Element)
function ajcelt_add_admin_menu() {
add_menu_page(
__('AJ Card Element', 'aj-card-element'),
__('AJ Card Element', 'aj-card-element'),
'manage_options',
'ajcelt-main-menu',
'ajcelt_documentation_page_callback',
'dashicons-images-alt',
20
);
// Optional: Add Documentation as submenu
add_submenu_page(
'ajcelt-main-menu',
__('Documentation', 'aj-card-element'),
__('Documentation', 'aj-card-element'),
'manage_options',
'ajcelt-documentation',
'ajcelt_documentation_page_callback'
);
}
add_action('admin_menu', 'ajcelt_add_admin_menu');
// Documentation
function ajcelt_documentation_page_callback() {
?>
AJ Card Element - Documentation
Use the shortcode below to display the latest posts from a specific category:
[ajcelt group_id="POST_ID"]
Steps to Use:
Go to AJ Card Element → Card Groups .
Enter a title for your card group (for internal reference).
Enter the desired category slug or ID for the group.
Specify the number of cards you want to display in each group.
Publish the card group to generate the shortcode.
Copy the generated shortcode and paste it anywhere (pages, posts, widgets).
Example:
If your card group has been created, then there will be a unique shortcode like-
[ajcelt group_id="123"]
Support:
For more detailed instructions, watch the video tutorial or contact our support team for assistance.
ID, 'accordion_content', true);
wp_nonce_field(basename(__FILE__), 'accordion_nonce');
echo '';
}
// Callback for URL Meta Box
function ajcelt_render_url_meta_box($post) {
$url = get_post_meta($post->ID, 'url_field', true);
wp_nonce_field(basename(__FILE__), 'url_nonce');
echo ' ';
}
// Callback for Bootstrap Icon Meta Box
function ajcelt_icon_meta_box_callback($post) {
$icon = get_post_meta($post->ID, '_ajcelt_bootstrap_icon', true);
wp_nonce_field('ajcelt_icon_meta_box', 'ajcelt_icon_meta_box_nonce');
echo ' ';
echo 'Browse Bootstrap Icons
';
}
// Callback for Select Group Meta Box
function ajcelt_tools_group_meta_callback($post) {
wp_nonce_field('ajcelt_group_meta_save', 'ajcelt_group_meta_nonce');
// Get all available groups
$groups = get_posts(array(
'post_type' => 'ajcelt_group', // Group post type slug
'posts_per_page' => -1, // Fetch all groups
));
// Get the current selected group
$group_id = get_post_meta($post->ID, 'ajcelt_group_id', true);
echo 'Select Group: ';
echo '';
echo 'Select a Group ';
// Loop through the groups and add them to the dropdown
foreach ($groups as $group) {
echo 'ID, $group_id, false) . '>' . esc_html($group->post_title) . ' ';
}
echo ' ';
}
// Save Custom Metadata
function ajcelt_save_custom_metadata($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
// Accordion Content
if (isset($_POST['accordion_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['accordion_nonce'])), basename(__FILE__))) {
if (isset($_POST['accordion_field'])) {
update_post_meta($post_id, 'accordion_content', sanitize_textarea_field(wp_unslash($_POST['accordion_field'])));
}
}
// URL Field
if (isset($_POST['url_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['url_nonce'])), basename(__FILE__))) {
if (isset($_POST['url_field'])) {
update_post_meta($post_id, 'url_field', esc_url_raw(wp_unslash($_POST['url_field'])));
}
}
// Bootstrap Icon
if (isset($_POST['ajcelt_icon_meta_box_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['ajcelt_icon_meta_box_nonce'])), 'ajcelt_icon_meta_box')) {
if (isset($_POST['ajcelt_bootstrap_icon'])) {
update_post_meta($post_id, '_ajcelt_bootstrap_icon', sanitize_text_field(wp_unslash($_POST['ajcelt_bootstrap_icon'])));
}
}
// Save Group Selection
if (isset($_POST['ajcelt_group_meta_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['ajcelt_group_meta_nonce'])), 'ajcelt_group_meta_save') && current_user_can('edit_post', $post_id)) {
if (isset($_POST['ajcelt_group_id'])) {
update_post_meta($post_id, 'ajcelt_group_id', sanitize_text_field(wp_unslash($_POST['ajcelt_group_id'])));
}
}
}
add_action('save_post', 'ajcelt_save_custom_metadata');
// Save Tool Group Meta
function ajcelt_save_tool_group_meta($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
// Save the group ID
if (isset($_POST['ajcelt_group_meta_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['ajcelt_group_meta_nonce'])), 'ajcelt_group_meta_save') && current_user_can('edit_post', $post_id)) {
if (isset($_POST['ajcelt_group_id'])) {
update_post_meta($post_id, 'ajcelt_group_id', sanitize_text_field(wp_unslash($_POST['ajcelt_group_id'])));
}
}
}
add_action('save_post', 'ajcelt_save_tool_group_meta');
// Number of Card
function ajcelt_add_group_metadata_fields() {
add_meta_box(
'group_layout_meta',
'Group Layout Options',
'ajcelt_render_group_layout_meta_box',
'ajcelt_group',
'side',
'default'
);
}
add_action('add_meta_boxes', 'ajcelt_add_group_metadata_fields');
// Render the meta box
function ajcelt_render_group_layout_meta_box($post) {
wp_nonce_field('ajcelt_group_layout_meta_save', 'ajcelt_group_layout_meta_nonce');
$cards_per_row = get_post_meta($post->ID, 'ajcelt_cards_per_row', true);
if (empty($cards_per_row)) {
$cards_per_row = 3; // default
}
echo 'Cards Per Row: ';
echo '';
for ($i = 1; $i <= 6; $i++) {
echo '' . esc_html($i) . ' ';
}
echo ' ';
}
function ajcelt_save_group_metadata($post_id) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if (isset($_POST['ajcelt_group_layout_meta_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['ajcelt_group_layout_meta_nonce'])), 'ajcelt_group_layout_meta_save')) {
if (isset($_POST['ajcelt_cards_per_row'])) {
update_post_meta($post_id, 'ajcelt_cards_per_row', sanitize_text_field(wp_unslash($_POST['ajcelt_cards_per_row'])));
}
}
}
add_action('save_post', 'ajcelt_save_group_metadata');
// 5. Shortcode Column
function ajcelt_add_shortcode_column($columns) {
$columns['ajcelt_shortcode'] = __('Shortcode', 'aj-card-element');
return $columns;
}
add_filter('manage_ajcelt_group_posts_columns', 'ajcelt_add_shortcode_column');
function ajcelt_render_shortcode_column($column, $post_id) {
if ($column === 'ajcelt_shortcode') {
echo '[ajcelt group_id="' . esc_attr($post_id) . '"]';
}
}
add_action('manage_ajcelt_group_posts_custom_column', 'ajcelt_render_shortcode_column', 10, 2);
// 6. Shortcode Output
function ajcelt_shortcode($atts) {
$atts = shortcode_atts(array(
'group_id' => '',
), $atts);
if (!$atts['group_id']) return 'No group ID provided.
';
$cards_per_row = get_post_meta($atts['group_id'], 'ajcelt_cards_per_row', true);
$cards_per_row_class = is_numeric($cards_per_row) && $cards_per_row > 0 ? 'ajcelt_cards-per-row-' . intval($cards_per_row) : 'ajcelt_cards-per-row-3';
// phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Custom field required, taxonomy not suitable
$args = array(
'post_type' => 'ajcelt_tool',
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'ajcelt_group_id',
'value' => $atts['group_id'],
'compare' => '='
)
),
'orderby' => 'date',
'order' => 'ASC',
);
$query = new WP_Query($args);
if (!$query->have_posts()) return 'No tools found in this group.
';
ob_start();
?>
add_section('ajcelt_section', array(
'title' => __('AJ Card Element Settings', 'aj-card-element'),
'priority' => 30,
));
// Icon Size Setting
$wp_customize->add_setting('ajcelt_icon_size', array(
'default' => '56px',
'transport' => 'refresh',
'sanitize_callback' => 'sanitize_text_field',
));
$wp_customize->add_control('ajcelt_icon_size', array(
'label' => __('Icon Size in PX', 'aj-card-element'),
'section' => 'ajcelt_section',
'type' => 'text',
'input_attrs' => array(
'placeholder' => 'Enter icon size in px (e.g., 56px)',
),
));
// Category Title Font Size
$wp_customize->add_setting('ajcelt_title_font_size', array(
'default' => '1.7rem',
'transport' => 'refresh',
'sanitize_callback' => 'sanitize_text_field',
));
$wp_customize->add_control('ajcelt_title_font_size', array(
'label' => __('Title Font Size', 'aj-card-element'),
'section' => 'ajcelt_section',
'type' => 'text',
));
// Image Size (width & height equal)
$wp_customize->add_setting('ajcelt_image_size', array(
'default' => '100px',
'transport' => 'refresh',
'sanitize_callback' => 'sanitize_text_field',
));
$wp_customize->add_control('ajcelt_image_size', array(
'label' => __('Image Size (Width & Height)', 'aj-card-element'),
'section' => 'ajcelt_section',
'type' => 'text',
));
// Paragraph Font Size in Card Body
$wp_customize->add_setting('ajcelt_paragraph_font_size', array(
'default' => '18px',
'transport' => 'refresh',
'sanitize_callback' => 'sanitize_text_field',
));
$wp_customize->add_control('ajcelt_paragraph_font_size', array(
'label' => __('Paragraph Font Size', 'aj-card-element'),
'section' => 'ajcelt_section',
'type' => 'text',
));
}
add_action('customize_register', 'ajcelt_customizer_settings');
function ajcelt_customizer_inline_css() {
$columns = absint(get_theme_mod('ajcelt_grid_columns', 3));
$title_font_size = esc_attr(get_theme_mod('ajcelt_title_font_size', '1.7rem'));
$image_size = esc_attr(get_theme_mod('ajcelt_image_size', '100px'));
$paragraph_font_size = esc_attr(get_theme_mod('ajcelt_paragraph_font_size', '18px'));
// First register style (even if empty)
wp_register_style('ajcelt-inline-style', false, [], AJCELT_VERSION);
// Now safely add inline styles
$custom_css = "
.ajcelt_tools-grid {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
padding: 5px;
max-width: 100%;
margin: 0 auto;
}
.ajcelt_category-title {
text-align: center;
margin-bottom: 2rem;
font-size: {$title_font_size};
color: #212529;
text-transform: capitalize;
}
.ajcelt_imageoverlay img {
width: {$image_size};
height: {$image_size};
border-radius: 50%;
padding: 5px;
border: 3px solid #ccc;
}
.ajcelt_card-bodyp p {
padding: 0 !important;
font-size: {$paragraph_font_size} !important;
}
@media (min-width: 992px) {
.ajcelt_tools-grid {
grid-template-columns: repeat({$columns}, 1fr);
}
}
";
// Correct order
wp_register_style('ajcelt-inline-style', false, [], AJCELT_VERSION);
wp_enqueue_style('ajcelt-inline-style');
wp_add_inline_style('ajcelt-inline-style', $custom_css);
}
add_action('wp_enqueue_scripts', 'ajcelt_customizer_inline_css');
?>