## For Developers

Product: Monogram - Personal Portfolio WordPress Theme
URL: https://hub.jkdevstudio.com/docs/monogram/tips-best-practices/for-developers
Updated: 2026-08-19

This section covers hooks, filters, CSS architecture, and JavaScript globals available for extending Monogram in a child theme or custom plugin.

## Action Hooks

<table style="min-width: 100px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>Hook</p></th><th colspan="1" rowspan="1"><p>Location</p></th><th colspan="1" rowspan="1"><p>Parameters</p></th><th colspan="1" rowspan="1"><p>Description</p></th></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_before_footer</code></p></td><td colspan="1" rowspan="1"><p>footer.php</p></td><td colspan="1" rowspan="1"><p>-</p></td><td colspan="1" rowspan="1"><p>Fires before the footer wrapper. Use to inject content above the footer.</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_before_page_content</code></p></td><td colspan="1" rowspan="1"><p>page.php</p></td><td colspan="1" rowspan="1"><p><code>$post_id</code></p></td><td colspan="1" rowspan="1"><p>Fires before page content output.</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_after_page_content</code></p></td><td colspan="1" rowspan="1"><p>page.php</p></td><td colspan="1" rowspan="1"><p><code>$post_id</code></p></td><td colspan="1" rowspan="1"><p>Fires after page content output.</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_after_portfolio</code></p></td><td colspan="1" rowspan="1"><p>portfolio/loop.php</p></td><td colspan="1" rowspan="1"><p>-</p></td><td colspan="1" rowspan="1"><p>Fires after the portfolio archive grid.</p></td></tr></tbody></table>

### Example: Add content before footer

```php
add_action('jkd_before_footer', function() {
    echo '<div class="custom-cta">Contact us today!</div>

';
});
```

## Filter Hooks

<table style="min-width: 100px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>Filter</p></th><th colspan="1" rowspan="1"><p>Default</p></th><th colspan="1" rowspan="1"><p>Parameters</p></th><th colspan="1" rowspan="1"><p>Description</p></th></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_page_content_classes</code></p></td><td colspan="1" rowspan="1"><p><code>[]</code></p></td><td colspan="1" rowspan="1"><p><code>$classes, $post_id</code></p></td><td colspan="1" rowspan="1"><p>CSS classes on page content wrapper</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_page_header_classes</code></p></td><td colspan="1" rowspan="1"><p><code>[]</code></p></td><td colspan="1" rowspan="1"><p><code>$classes</code></p></td><td colspan="1" rowspan="1"><p>CSS classes on page header</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_page_header_title</code></p></td><td colspan="1" rowspan="1"><p>Auto-detected</p></td><td colspan="1" rowspan="1"><p><code>$title</code></p></td><td colspan="1" rowspan="1"><p>Page header title text</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_page_header_subtitle</code></p></td><td colspan="1" rowspan="1"><p><code>''</code></p></td><td colspan="1" rowspan="1"><p><code>$subtitle</code></p></td><td colspan="1" rowspan="1"><p>Page header subtitle</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_footer_classes</code></p></td><td colspan="1" rowspan="1"><p><code>[]</code></p></td><td colspan="1" rowspan="1"><p><code>$classes</code></p></td><td colspan="1" rowspan="1"><p>Footer wrapper CSS classes</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_footer_tagline</code></p></td><td colspan="1" rowspan="1"><p>Setting value</p></td><td colspan="1" rowspan="1"><p><code>$tagline</code></p></td><td colspan="1" rowspan="1"><p>Footer tagline text</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_footer_copyright</code></p></td><td colspan="1" rowspan="1"><p>Setting value</p></td><td colspan="1" rowspan="1"><p><code>$copyright, $style</code></p></td><td colspan="1" rowspan="1"><p>Copyright text</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_footer_social_items</code></p></td><td colspan="1" rowspan="1"><p>Setting value</p></td><td colspan="1" rowspan="1"><p><code>$items, $style</code></p></td><td colspan="1" rowspan="1"><p>Social links array</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_footer_contact_data</code></p></td><td colspan="1" rowspan="1"><p>Setting value</p></td><td colspan="1" rowspan="1"><p><code>$data</code></p></td><td colspan="1" rowspan="1"><p>Footer contact information</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_nav_logo_url</code></p></td><td colspan="1" rowspan="1"><p>Setting value</p></td><td colspan="1" rowspan="1"><p><code>$url, $context</code></p></td><td colspan="1" rowspan="1"><p>Navigation logo URL</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_nav_cta_args</code></p></td><td colspan="1" rowspan="1"><p>Setting value</p></td><td colspan="1" rowspan="1"><p><code>$args</code></p></td><td colspan="1" rowspan="1"><p>Nav CTA button arguments</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_nav_social_items</code></p></td><td colspan="1" rowspan="1"><p>Setting value</p></td><td colspan="1" rowspan="1"><p><code>$items</code></p></td><td colspan="1" rowspan="1"><p>Nav social links</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_walker_max_items</code></p></td><td colspan="1" rowspan="1"><p><code>7</code></p></td><td colspan="1" rowspan="1"><p><code>$count</code></p></td><td colspan="1" rowspan="1"><p>Max top-level menu items before overflow</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_localize_ajax</code></p></td><td colspan="1" rowspan="1"><p>AJAX data</p></td><td colspan="1" rowspan="1"><p><code>$data</code></p></td><td colspan="1" rowspan="1"><p>Localized AJAX data passed to JS</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>jkd_localize_settings</code></p></td><td colspan="1" rowspan="1"><p>Settings data</p></td><td colspan="1" rowspan="1"><p><code>$data</code></p></td><td colspan="1" rowspan="1"><p>Localized settings passed to JS</p></td></tr></tbody></table>

### Example: Change max menu items

```php
add_filter('jkd_walker_max_items', function() {
    return 9;
});
```

## JavaScript Globals

<table style="min-width: 50px;"><colgroup><col style="min-width: 25px;"><col style="min-width: 25px;"></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>Global</p></th><th colspan="1" rowspan="1"><p>Description</p></th></tr><tr><td colspan="1" rowspan="1"><p><code>window.jkdGetSetting(key, fallback)</code></p></td><td colspan="1" rowspan="1"><p>Read Customizer setting. Supports URL param override for testing.</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>window.isMobile()</code></p></td><td colspan="1" rowspan="1"><p>Returns true on mobile devices (768px breakpoint + UA check). Cached, resets on resize.</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>window.jkdPlaySound(name)</code></p></td><td colspan="1" rowspan="1"><p>Trigger a sound effect programmatically. Names: hover, click, toggle, submit, open, close, success, error</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>window.jkdLazyLoad.refresh(root)</code></p></td><td colspan="1" rowspan="1"><p>Re-trigger lazy loading on newly injected DOM content</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>window.jkd_settings.kirki</code></p></td><td colspan="1" rowspan="1"><p>All Customizer settings object</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>window.jkd_ajax.ajaxurl</code></p></td><td colspan="1" rowspan="1"><p>WordPress AJAX endpoint URL</p></td></tr></tbody></table>

## CSS Custom Properties

```css
/* Border radius */
--jkd-br-sm: 5px;
--jkd-br-md: 8px;
--jkd-br-lg: 15px;
--jkd-br-xl: 50px;

/* Opacity */
--jkd-op-xl: 0.15;
--jkd-op-lg: 0.42;
--jkd-op-md: 0.62;
--jkd-op-sm: 0.82;

/* Transitions */
--jkd-tr-dr: 0.255s;
--jkd-tr-tp: cubic-bezier(0.4, 0, 0.2, 1);

/* Color scheme (set dynamically) */
--jkd-accent, --jkd-bg, --jkd-bg-secondary,
--jkd-text, --jkd-heading, --jkd-border
```

## Child Theme

Install `monogram-child.zip` from the theme package. Override any template by copying it from the parent theme into the child theme, maintaining the directory structure.

Example: to override the portfolio single template, copy `template-parts/portfolio/single.php` to your child theme at the same path.

<div data-callout="warning">

Never edit parent theme files directly. All customizations should go in your child theme or a custom plugin to survive theme updates.

</div>