Use notifal/template/import/result to observe or modify the outcome after Notifal imports one or more notifal_template posts from a JSON or ZIP upload.
The filter is applied at the end of Importer::importFromFile() in the Templates module, after FileImportHelper::processFileImport() aggregates per-file results. The AJAX import controller (ImportController) uses the same filter constant.
Hook reference: Hooks: Templates and Rendering.
Result array shape
After processing, $result contains:
| Key | Type | Description |
|---|---|---|
success | int | Count of successfully imported templates |
failed | int | Count of failed imports |
errors | array | List of error message strings |
first_title | string | Title of the first imported template (Templates module adds this) |
is_zip | bool | Present when the upload was handled as a ZIP archive |
Each internal JSON import returns { success: bool, template_id?: int, error?: string } before aggregation.
The filter receives the absolute $filePath of the uploaded temp file as the second argument.
Related import filters (during creation)
These run inside the importer before the final result filter:
| Filter | Purpose |
|---|---|
notifal/template/import/post_status | Default post status (publish, draft, private) |
notifal/template/default_title | Title before post insert |
notifal/template/final_title | Title after post insert |
Use notifal/template/import/result when you need a single place to react to the full batch outcome (logging, admin notices, webhooks).
Example: log import outcomes
<?php
/**
* Plugin Name: My Notifal Import Logger
* Description: Logs Notifal template import results.
* Version: 1.0.0
* Requires PHP: 7.4
*/
defined( 'ABSPATH' ) || exit;
use Notifal\Infrastructure\WordPress\Hooks\FilterHooks;
/**
* Register the template import result filter.
*
* @return void
*/
add_action( 'plugins_loaded', 'my_notifal_register_template_import_filter' );
/**
* Attach filter when Notifal is available.
*
* @return void
*/
function my_notifal_register_template_import_filter(): void {
if ( ! defined( 'NOTIFAL_VERSION' ) ) {
return;
}
add_filter( FilterHooks::TEMPLATE_IMPORT_RESULT, 'my_notifal_log_template_import_result', 10, 2 );
}
/**
* Write a concise log entry for each template import batch.
*
* @param array<string, mixed> $result Aggregated import result from Importer.
* @param string $filePath Absolute path to the uploaded import file.
* @return array<string, mixed> Unmodified result (pass-through filter).
*/
function my_notifal_log_template_import_result( array $result, string $filePath ): array {
// Normalize counters with absint for safe logging.
$success = isset( $result['success'] ) ? absint( $result['success'] ) : 0;
$failed = isset( $result['failed'] ) ? absint( $result['failed'] ) : 0;
// Build a safe basename for the log line (never log full server paths in production UI).
$basename = sanitize_file_name( wp_basename( $filePath ) );
// Compose a single log message string.
$message = sprintf(
'Notifal template import: %1$d succeeded, %2$d failed (file: %3$s)',
$success,
$failed,
$basename
);
// Write to the WordPress debug log when WP_DEBUG_LOG is enabled.
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- intentional audit trail.
error_log( $message );
}
return $result;
}
Example: append metadata for your admin UI
<?php
defined( 'ABSPATH' ) || exit;
use Notifal\Infrastructure\WordPress\Hooks\FilterHooks;
add_filter( FilterHooks::TEMPLATE_IMPORT_RESULT, function ( array $result, string $filePath ): array {
// Flag marketplace ZIP imports based on filename convention.
$basename = sanitize_file_name( wp_basename( $filePath ) );
$is_marketplace = (bool) preg_match( '/^notifal-marketplace-/i', $basename );
// Attach a namespaced meta block for your plugin (AJAX consumers can read this).
$result['my_import_meta'] = [
'source' => $is_marketplace ? 'marketplace' : 'manual',
'imported_at' => gmdate( 'c' ),
'file_basename' => $basename,
];
// Surface a friendly admin message when at least one template succeeded.
if ( ! empty( $result['success'] ) && absint( $result['success'] ) > 0 ) {
$title = isset( $result['first_title'] ) ? sanitize_text_field( (string) $result['first_title'] ) : '';
$result['my_admin_notice'] = $title !== ''
? sprintf(
/* translators: %s: imported template title */
__( 'Imported template: %s', 'my-notifal-import' ),
$title
)
: __( 'Template import completed.', 'my-notifal-import' );
}
return $result;
}, 10, 2 );
If you display my_admin_notice in the browser, escape on output with esc_html().
Example: force draft status via companion filter
Combine with notifal/template/import/post_status when imports from untrusted sources should not publish immediately:
<?php
defined( 'ABSPATH' ) || exit;
use Notifal\Infrastructure\WordPress\Hooks\FilterHooks;
// Set draft status before the template post is inserted.
add_filter(
FilterHooks::TEMPLATE_IMPORT_POST_STATUS,
function ( string $status, array $template_data ): string {
// Mark third-party bundles as draft until an editor approves them.
if ( ! empty( $template_data['source'] ) && sanitize_key( (string) $template_data['source'] ) === 'external' ) {
return 'draft';
}
return $status;
},
10,
2
);
Validation rules
Invalid import packages are rejected. Supported builders are Elementor, Block Editor, and HTML Builder. Duplicate content may be skipped when Notifal detects an identical imported template.
What to read next
Cookbook series
- Cookbook: Modify Notification Before Display
- Cookbook: Add Custom Dynamic Tag
- Cookbook: Customize Template Import (you are here)
- Cookbook: Extend Display Rules
- Cookbook: Register a Custom HTML Builder Widget