WordPress.org

Make WordPress Core

Opened 7 years ago

Last modified 8 weeks ago

#7795 assigned enhancement

Activate and Deactivate Theme hooks

Reported by: jacobsantos Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 2.7
Component: Themes Keywords: revert needs-refresh
Focuses: Cc:

Description

Currently, there is no standard way of checking whether of theme is activated, deactivated and uninstalled. Plugins have this capability and themes should also have the same to ensure that both share similar functionality.

Attachments (2)

7795.diff (3.9 KB) - added by DD32 7 years ago.
7795_chrisbliss18.diff (568 bytes) - added by chrisbliss18 6 years ago.

Download all attachments as: .zip

Change History (43)

comment:1 @jacobsantos7 years ago

  • Status changed from new to assigned

comment:2 @westi7 years ago

  • Cc westi added

comment:3 @DD327 years ago

Marked #7556 as duplicate of this.

comment:5 @ionfish7 years ago

  • Keywords needs-patch added
  • Version set to 2.7

comment:6 @ionfish7 years ago

See also #8652.

comment:7 @DD327 years ago

Hm.. Just started implementing this.

How to handle theme activation.. It would be possible to include both themes at once, that would be the simplest way, but could cause issues if themes duplicate functions.

could run the activation hook on the page reload, so that only 1 theme is included at once.. Thoughts?

@DD327 years ago

comment:8 @DD327 years ago

  • Keywords has-patch needs-testing added; needs-patch removed
  • Owner changed from jacobsantos to anonymous
  • Status changed from assigned to new

attachment 7795.diff added.

  • Downside: Theme activation hooks are only run if the theme is activated via the theme panel, Other custom methods will need to call the run_theme_activation_hook() function manually after including the theme.
  • uses register_theme_activation_hook(__FILE__, 'function') and register_theme_deactivation_hook(__FILE__, 'function') syntax, Must be called from a file within the themes directory, but NOT in a subdirectory.
  • Activation hook is run on a page refresh, So activation has 2 redirects, It would be possible to remove the wp_redirect() and exit lines from the theme_activate if block, but the URL would be messy, and any output from the themes activation function would be shown.. Seemed best to redirect again

Example use: (in a themes functions.php)

add_action('generate_rewrite_rules', 'theme_add_rewrite_rules', 100);
function theme_add_rewrite_rules( $wp_rewrite ) {
	$new_rules = array( '^redirect-me/?$' => 'index.php?pagename=to-something-else' );
	$wp_rewrite->rules = $new_rules + (array)$wp_rewrite->rules;
}

register_theme_activation_hook(__FILE__, 'theme_activate');
function theme_activate() {
	global $wp_rewrite;
	$wp_rewrite->flush_rules();
}

register_theme_deactivation_hook(__FILE__, 'theme_deactivate');
function theme_deactivate() {
	global $wp_rewrite;
	remove_action('generate_rewrite_rules', 'theme_add_rewrite_rules', 100);
	$wp_rewrite->flush_rules();
}

(Hope you dont mind me clearing the assigned status jacobsantos)

comment:9 @jacobsantos7 years ago

I don't mind you replacing me as the assigned, since you've done the most work anyway. I just like being able to track tickets without having to do a search for 'cc' or reporter. I always seem to forget which on I've used.

I don't see why the functions need to be in the themes directory and not a subdirectory. It appears to work just like the plugins activation and deactivation hook. You are hooking into the file name of the main theme, in which case it will always be THEME_NAME/functions.php, which does make it easier. It means that they'll just have to include the file that has those functions in their main file.

This weekend I think I'm going to test it and see how it goes. Hopefully more people will test it.

comment:10 @DD327 years ago

You are hooking into the file name of the main theme, in which case it will always be THEME_NAME/functions.php

Errr... 'doh! Here was I thinking i needed to check which theme it was coming from -- Err, Actually, You do need to. In the case of a child and parent theme, you'd want both activation hooks to run, and as such, you'd need to be able to tell which one is calling.

The reason for the "must be in theme root" was because of the __FILE__ -> theme name, __FILE__ returns c:\...\..\ on windows, and the Theme dir constant is C:\...\..../wp-content/..... so a simple str_replace and all that would need to be done, And i was thinking of optimization at the time, its code thats potentially going to run on every page load (I guess a !is_admin() line could short circuit it?

The other option would've been to do:

$theme = preg_replace('|^.*/themes/|', '', dirname($file));
$theme = preg_replace('|[/\\\].*$|', '', $theme);

OR
$theme = preg_replace('|^.*/themes/|', '', dirname($file));
if ( $pos = strpos($theme, '/') )
   $theme = substr($theme, 0, $pos);

(Since /themes/ is hard-coded)

I'm really open to suggestions on a better way there..

comment:11 @DD326 years ago

  • Keywords needs-patch dev-feedback added; theme API has-patch needs-testing removed

Patch is now stale.

Implementation wanted for 2.8, or future?

comment:12 @ionfish6 years ago

Adding this in 2.8 would be really valuable.

comment:13 @Denis-de-Bernardy6 years ago

  • Milestone changed from 2.8 to Future Release

moving to Future pending a patch

comment:14 @Denis-de-Bernardy6 years ago

  • Keywords dev-feedback removed

comment:15 @Denis-de-Bernardy6 years ago

  • Component changed from Template to Themes
  • Milestone changed from Future Release to 2.9

comment:16 @ryan6 years ago

  • Milestone changed from 2.9 to Future Release

comment:17 @demetris5 years ago

  • Cc dkikizas@… added

comment:18 @christian_gnoth5 years ago

  • Version changed from 2.7 to 3.0.1

in 3.0.1 still there is no hhok for the theme activate event

comment:19 @demetris5 years ago

  • Version changed from 3.0.1 to 2.7

@christian_gnoth

The Version number is the WP version for which the issue was first reported, and it must not be changed.

comment:20 @WraithKenny5 years ago

  • Cc Ken@… added

More and more Theme's are taking the idea that the function file is virtually the same as a plugin to heart and adding options... Options which can not be removed easily by users since there is no uninstall support for themes as there is with plugins. This leads to a build up of useless data.

I'm of the opinion that Theme's are mature enough at this point to gain this functionality that plugins already have.

Anyone interested in a fresh look at this ticket?

comment:21 @nacin5 years ago

As indicated in #14849 I think one option would be to have an autoloaded option to keep track of whether a theme activation hook needs to be fired.

comment:22 @scribu5 years ago

  • Cc scribu added

comment:23 @christian_gnoth5 years ago

as themes are activated, it should be no problem to call a seperate function for

deactivation
and
activation

the deactivation function should be called for the old theme and the activation function for the new theme.
then through a hook the theme developer can fill that functions with actions.

comment:24 @scribu5 years ago

For the deactivation hook to work, the functions.php of the old theme has to be loaded. I think the most logical time to call it would be just before switching to the new theme.

comment:25 @dd325 years ago

For the deactivation hook to work, the functions.php of the old theme has to be loaded. I think the most logical time to call it would be just before switching to the new theme.

Current generation themes utilise the 'switch_themes' action, which fires on the processing of the theme-change option. That should be the last "page load" which utilises that theme in its current state.

comment:26 @azizur5 years ago

  • Cc prodevstudio+wordpress@… added

comment:27 @scribu5 years ago

Related: #14955

comment:28 @kksharma16185 years ago

  • Cc kksharma1618 added

I have written a code which provides a reliable activation/deactivation theme hooks. Please check it out and let me know what you guys think!

http://www.krishnakantsharma.com/2011/01/activationdeactivation-hook-for-wordpress-theme/

Note: Though this can be used in core and it will work well with themes, I think if we are modifying core then we can place a more direct code, instead of this indirect patch.

comment:29 @scribu4 years ago

  • Keywords needs-patch removed
  • Milestone changed from Future Release to 3.3
  • Resolution set to fixed
  • Status changed from new to closed

So, we alredy had a theme deactivation hook and now we have theme activation hook as well, since [18656]:

Theme activation hook: 'after_switch_theme'

Theme de-activation hook: 'switch_theme'

It's a little backwards from a theme author's perspective, but it works.

comment:30 @nacin4 years ago

  • Keywords revert added
  • Resolution fixed deleted
  • Status changed from closed to reopened

Reopening. See comment 86 in #17979.

comment:31 @scribu4 years ago

  • Milestone changed from 3.3 to Future Release

Guess we don't actually have an API for this currently.

comment:32 @Mamaduka3 years ago

  • Cc georgemamadashvili@… added

comment:33 @stephenh19883 years ago

  • Cc stephen@… added

comment:34 @jacobsantos3 years ago

  • Owner anonymous deleted
  • Status changed from reopened to assigned

comment:35 @CreativeInfusion3 years ago

Sorry if I've misunderstood (my first comment here), but hasn't this been resolved first in WP 3.3 by scribu ticket:17979:83 and then patched by #20334 in WP 3.4?

The activation hook after_switch_theme is referenced in the in the codex register_post_type so I presume it's supposed to be used (I hope so as I've started using it for start up code in bespoke themes).

Deactivation hook is switch_theme.

Theme uninstallation is the sole topic of #14955

Suggest closure.

Last edited 3 years ago by SergeyBiryukov (previous) (diff)

comment:36 @TomAuger3 years ago

  • Cc tomaugerdotcom@… added

comment:37 @egorpromo3 years ago

Theme deactivation hook: 'after_switch_theme'
Theme activation hook: 'switch_theme'

That is my opinion. I've made tests.

//Deactivation
add_action( 'after_switch_theme', 'my_deactivation' );
function my_deactivation($old_theme)
{
	echo '<h1>Deactivation for '.$old_theme.'</h1>';
}

//Activation
add_action("switch_theme", "my_activation", 10 , 2);
function my_activation($new_theme_name, $new_theme_class)
{
	echo '<h1>my_activation()</h1>';
	echo '<pre>';
	var_dump($new_theme_name);
	echo '</pre>';

	echo '<pre>';
	var_dump($new_theme_class);
	echo '</pre>';
}

Tested on version 3.4.2

But if wordpress's theme wants do something before it will be uninstalled, It needs hook to "switch_theme" hook. Because later there is no opportunity for theme to execute something.

Last edited 3 years ago by egorpromo (previous) (diff)

comment:38 @Veraxus3 years ago

That's not entirely accurate egorpromo...

'after_switch_theme' is run by a NEW theme after the switch occurs (I'm not sure why $old_theme was chosen to be passed as an argument, but it has no bearing on the actual point where the action is run). Hence, it runs on activation.

'switch_theme' is run when a switch is initiated... by the OLD theme, before the actual switch takes place. Hence, it runs on deactivation.

comment:39 @retlehs2 years ago

  • Cc retlehs added

comment:40 @DeanMarkTaylor2 years ago

  • Cc DeanMarkTaylor added

comment:41 @abdessamad idrissi8 weeks ago

  • Keywords needs-refresh added

Any updates on this after 7 years? A quick fix would be now to use switch_theme hook and filter the passed $theme argument to see if it is the current them then if not return;

Note: See TracTickets for help on using tickets.