/** * Physics Forum Theme - functions.php */ if ( ! defined( 'ABSPATH' ) ) exit; /* ─── Theme Setup ─────────────────────────────── */ function pf_setup() { add_theme_support( 'automatic-feed-links' ); add_theme_support( 'title-tag' ); add_theme_support( 'post-thumbnails' ); add_theme_support( 'html5', [ 'search-form','comment-form','comment-list','gallery','caption','style','script' ] ); add_theme_support( 'custom-logo', [ 'height' => 80, 'width' => 260, 'flex-height' => true, 'flex-width' => true, ]); add_theme_support( 'customize-selective-refresh-widgets' ); register_nav_menus([ 'primary' => __( 'Primary Navigation', 'physics-forum' ), 'footer_1' => __( 'Footer Navigation 1', 'physics-forum' ), 'footer_2' => __( 'Footer Navigation 2', 'physics-forum' ), 'footer_3' => __( 'Footer Navigation 3', 'physics-forum' ), ]); add_image_size( 'pf-featured', 900, 500, true ); add_image_size( 'pf-thumbnail', 480, 300, true ); add_image_size( 'pf-square', 300, 300, true ); load_theme_textdomain( 'physics-forum', get_template_directory() . '/languages' ); } add_action( 'after_setup_theme', 'pf_setup' ); /* ─── Content Width ───────────────────────────── */ function pf_content_width() { $GLOBALS['content_width'] = 900; } add_action( 'after_setup_theme', 'pf_content_width', 0 ); /* ─── Enqueue Scripts & Styles ────────────────── */ function pf_scripts() { // Google Fonts wp_enqueue_style( 'pf-google-fonts', 'https://fonts.googleapis.com/css2?family=Orbitron:wght@400;600;700;800;900&family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Space+Grotesk:wght@400;500;600;700&display=swap', [], null ); // Font Awesome wp_enqueue_style( 'pf-fontawesome', 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css', [], '6.5.0' ); // Main stylesheet wp_enqueue_style( 'physics-forum-style', get_stylesheet_uri(), [ 'pf-google-fonts' ], wp_get_theme()->get('Version') ); // Custom CSS overrides wp_enqueue_style( 'pf-custom', get_template_directory_uri() . '/assets/css/custom.css', [ 'physics-forum-style' ], wp_get_theme()->get('Version') ); // Main JS wp_enqueue_script( 'pf-main', get_template_directory_uri() . '/assets/js/main.js', [], wp_get_theme()->get('Version'), true ); // Particles JS wp_enqueue_script( 'pf-particles', get_template_directory_uri() . '/assets/js/particles.js', [], wp_get_theme()->get('Version'), true ); // Collider JS (only on collider page) if ( is_page_template('page-collider.php') || is_front_page() ) { wp_enqueue_script( 'pf-collider', get_template_directory_uri() . '/assets/js/collider.js', ['pf-main'], wp_get_theme()->get('Version'), true ); } if ( is_singular() && comments_open() && get_option('thread_comments') ) { wp_enqueue_script( 'comment-reply' ); } // Localize wp_localize_script( 'pf-main', 'pfData', [ 'ajaxUrl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('pf-nonce'), 'themeUrl' => get_template_directory_uri(), 'siteUrl' => home_url(), ]); } add_action( 'wp_enqueue_scripts', 'pf_scripts' ); /* ─── Widgets ─────────────────────────────────── */ function pf_widgets_init() { $defaults = [ 'before_widget' => '
', 'after_widget' => '
', 'before_title' => '

', 'after_title' => '

', ]; register_sidebar( array_merge($defaults, [ 'name' => __('Sidebar', 'physics-forum'), 'id' => 'sidebar-1', 'description' => __('Main sidebar widgets.', 'physics-forum'), ])); register_sidebar( array_merge($defaults, [ 'name' => __('Footer Column 1', 'physics-forum'), 'id' => 'footer-1', 'description' => __('Footer column 1 widgets.', 'physics-forum'), ])); } add_action( 'widgets_init', 'pf_widgets_init' ); /* ─── Custom Post Types ───────────────────────── */ function pf_register_post_types() { // Thought Experiments register_post_type('thought_experiment', [ 'labels' => [ 'name' => __('Thought Experiments', 'physics-forum'), 'singular_name' => __('Thought Experiment', 'physics-forum'), 'add_new_item' => __('Add New Thought Experiment', 'physics-forum'), ], 'public' => true, 'has_archive' => true, 'menu_icon' => 'dashicons-lightbulb', 'supports' => ['title','editor','author','thumbnail','excerpt','comments'], 'rewrite' => ['slug' => 'thought-experiments'], 'show_in_rest' => true, ]); // Discoveries register_post_type('discovery', [ 'labels' => [ 'name' => __('Discoveries', 'physics-forum'), 'singular_name' => __('Discovery', 'physics-forum'), 'add_new_item' => __('Add New Discovery', 'physics-forum'), ], 'public' => true, 'has_archive' => true, 'menu_icon' => 'dashicons-star-filled', 'supports' => ['title','editor','author','thumbnail','excerpt'], 'rewrite' => ['slug' => 'discoveries'], 'show_in_rest' => true, ]); // Mysteries / Bounties register_post_type('mystery', [ 'labels' => [ 'name' => __('Unsolved Mysteries', 'physics-forum'), 'singular_name' => __('Mystery', 'physics-forum'), 'add_new_item' => __('Add New Mystery', 'physics-forum'), ], 'public' => true, 'has_archive' => true, 'menu_icon' => 'dashicons-search', 'supports' => ['title','editor','author','thumbnail','excerpt'], 'rewrite' => ['slug' => 'mysteries'], 'show_in_rest' => true, ]); } add_action( 'init', 'pf_register_post_types' ); /* ─── Custom Taxonomies ───────────────────────── */ function pf_register_taxonomies() { register_taxonomy('physics_field', ['post','thought_experiment','discovery','mystery'], [ 'labels' => [ 'name' => __('Physics Fields', 'physics-forum'), 'singular_name' => __('Physics Field', 'physics-forum'), ], 'hierarchical' => true, 'public' => true, 'rewrite' => ['slug' => 'field'], 'show_in_rest' => true, ]); } add_action( 'init', 'pf_register_taxonomies' ); /* ─── Custom Meta Boxes ───────────────────────── */ function pf_add_meta_boxes() { add_meta_box('pf-mystery-bounty', __('Bounty & Details','physics-forum'), 'pf_mystery_meta_box', 'mystery', 'side'); add_meta_box('pf-discovery-source', __('Source Details','physics-forum'), 'pf_discovery_meta_box', 'discovery', 'side'); add_meta_box('pf-experiment-difficulty', __('Experiment Details','physics-forum'), 'pf_experiment_meta_box', 'thought_experiment', 'side'); } add_action('add_meta_boxes', 'pf_add_meta_boxes'); function pf_mystery_meta_box($post) { $bounty = get_post_meta($post->ID, '_pf_bounty', true); $attempts = get_post_meta($post->ID, '_pf_attempts', true); $status = get_post_meta($post->ID, '_pf_status', true); wp_nonce_field('pf_mystery_meta', 'pf_mystery_nonce'); echo '

'; echo '

'; echo '

'; } function pf_discovery_meta_box($post) { $source = get_post_meta($post->ID, '_pf_source', true); $journal = get_post_meta($post->ID, '_pf_journal', true); wp_nonce_field('pf_discovery_meta', 'pf_discovery_nonce'); echo '

'; echo '

'; } function pf_experiment_meta_box($post) { $difficulty = get_post_meta($post->ID, '_pf_difficulty', true); $field_branch = get_post_meta($post->ID, '_pf_field_branch', true); wp_nonce_field('pf_experiment_meta', 'pf_experiment_nonce'); echo '

'; echo '

'; } /* ─── Save Meta Boxes ─────────────────────────── */ function pf_save_meta($post_id) { if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return; if (!current_user_can('edit_post', $post_id)) return; if (isset($_POST['pf_mystery_nonce']) && wp_verify_nonce($_POST['pf_mystery_nonce'], 'pf_mystery_meta')) { if (isset($_POST['pf_bounty'])) update_post_meta($post_id, '_pf_bounty', sanitize_text_field($_POST['pf_bounty'])); if (isset($_POST['pf_attempts'])) update_post_meta($post_id, '_pf_attempts', sanitize_text_field($_POST['pf_attempts'])); if (isset($_POST['pf_status'])) update_post_meta($post_id, '_pf_status', sanitize_text_field($_POST['pf_status'])); } if (isset($_POST['pf_discovery_nonce']) && wp_verify_nonce($_POST['pf_discovery_nonce'], 'pf_discovery_meta')) { if (isset($_POST['pf_source'])) update_post_meta($post_id, '_pf_source', esc_url_raw($_POST['pf_source'])); if (isset($_POST['pf_journal'])) update_post_meta($post_id, '_pf_journal', sanitize_text_field($_POST['pf_journal'])); } if (isset($_POST['pf_experiment_nonce']) && wp_verify_nonce($_POST['pf_experiment_nonce'], 'pf_experiment_meta')) { if (isset($_POST['pf_difficulty'])) update_post_meta($post_id, '_pf_difficulty', sanitize_text_field($_POST['pf_difficulty'])); if (isset($_POST['pf_field_branch'])) update_post_meta($post_id, '_pf_field_branch', sanitize_text_field($_POST['pf_field_branch'])); } } add_action('save_post', 'pf_save_meta'); /* ─── Helper: Get Initials Avatar ─────────────── */ function pf_get_avatar($name, $size='md', $color_index=0) { $colors = [ ['bg'=>'rgba(56,189,248,0.25)','text'=>'#38bdf8'], ['bg'=>'rgba(168,85,247,0.25)','text'=>'#a855f7'], ['bg'=>'rgba(16,185,129,0.25)','text'=>'#10b981'], ['bg'=>'rgba(249,115,22,0.25)','text'=>'#f97316'], ['bg'=>'rgba(236,72,153,0.25)','text'=>'#ec4899'], ]; $c = $colors[$color_index % count($colors)]; $parts = explode(' ', $name); $initials = strtoupper(substr($parts[0],0,1) . (isset($parts[1]) ? substr($parts[1],0,1) : '')); $sz_class = $size === 'lg' ? 'avatar-lg' : ''; return '
' . esc_html($initials) . '
'; } /* ─── Helper: Difficulty Badge ────────────────── */ function pf_difficulty_badge($difficulty) { $map = [ 'beginner' => ['class'=>'badge-green', 'icon'=>'fa-seedling'], 'intermediate' => ['class'=>'badge-blue', 'icon'=>'fa-atom'], 'advanced' => ['class'=>'badge-purple', 'icon'=>'fa-flask'], 'expert' => ['class'=>'badge-pink', 'icon'=>'fa-brain'], ]; $d = $map[$difficulty] ?? $map['intermediate']; return ' ' . ucfirst($difficulty) . ''; } /* ─── Excerpt Length ──────────────────────────── */ function pf_excerpt_length($length) { return 25; } add_filter('excerpt_length', 'pf_excerpt_length'); function pf_excerpt_more($more) { return '...'; } add_filter('excerpt_more', 'pf_excerpt_more'); /* ─── Body Classes ────────────────────────────── */ function pf_body_classes($classes) { if (is_front_page()) $classes[] = 'is-front-page'; if (is_page_template('page-collider.php')) $classes[] = 'is-collider'; return $classes; } add_filter('body_class', 'pf_body_classes'); /* ─── Customizer ──────────────────────────────── */ function pf_customize_register($wp_customize) { $wp_customize->add_section('pf_general', [ 'title' => __('Physics Forum Settings','physics-forum'), 'priority' => 25, ]); $settings = [ 'pf_hero_title' => ['label'=>'Hero Title', 'default'=>'Where Physics Meets Curiosity'], 'pf_hero_subtitle' => ['label'=>'Hero Subtitle', 'default'=>'A community where physicists, researchers, and curious minds converge to explore the fundamental laws of the universe.'], 'pf_footer_text' => ['label'=>'Footer Text', 'default'=>'A community where physicists, researchers, and curious minds converge.'], ]; foreach ($settings as $id => $args) { $wp_customize->add_setting($id, ['default'=>$args['default'], 'sanitize_callback'=>'sanitize_text_field', 'transport'=>'refresh']); $wp_customize->add_control($id, ['label'=>$args['label'], 'section'=>'pf_general', 'type'=>'text']); } } add_action('customize_register', 'pf_customize_register'); /* ─── AJAX: Load More Posts ───────────────────── */ function pf_load_more_posts() { check_ajax_referer('pf-nonce','nonce'); $type = sanitize_text_field($_POST['post_type'] ?? 'post'); $page = intval($_POST['page'] ?? 1); $count = intval($_POST['count'] ?? 6); $q = new WP_Query(['post_type'=>$type,'posts_per_page'=>$count,'paged'=>$page]); $data = []; if ($q->have_posts()) { while ($q->have_posts()) { $q->the_post(); $data[] = [ 'id' => get_the_ID(), 'title' => get_the_title(), 'excerpt' => get_the_excerpt(), 'link' => get_permalink(), 'date' => get_the_date('M j'), 'author' => get_the_author(), ]; } wp_reset_postdata(); } wp_send_json_success(['posts'=>$data,'has_more'=>$q->max_num_pages > $page]); } add_action('wp_ajax_pf_load_more', 'pf_load_more_posts'); add_action('wp_ajax_nopriv_pf_load_more', 'pf_load_more_posts'); /* ─── Custom Nav Walker ───────────────────────── */ class PF_Nav_Walker extends Walker_Nav_Menu { function start_el(&$output, $item, $depth=0, $args=null, $id=0) { $classes = empty($item->classes) ? [] : (array) $item->classes; $class_str = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args)); $atts = []; $atts['href'] = !empty($item->url) ? $item->url : '#'; $atts['target'] = !empty($item->target) ? $item->target : ''; $atts['rel'] = !empty($item->xfn) ? $item->xfn : ''; $atts['class'] = in_array('current-menu-item', $classes) ? 'current-menu-item' : ''; $atts['aria-current'] = $item->current ? 'page' : ''; $atts_str = ''; foreach ($atts as $attr => $value) { if (!empty($value)) $atts_str .= ' ' . $attr . '="' . esc_attr($value) . '"'; } $title = apply_filters('the_title', $item->title, $item->ID); $output .= '
  • '; $output .= '' . esc_html($title) . ''; } } Log In ‹ Physics Forum — WordPress

    Log In

    Powered by WordPress

    Error: Cookies are blocked due to unexpected output. For help, please see this documentation or try the support forums.

    ← Go to Physics Forum