How do you force a script to refire on every page load in Discourse?

Oh wow :scream: That is exactly what I’ve been searching for for the last 3 months! :heart::heart::heart:

This is really good @vinothkannans, thank you so much!

It works for me like this:

var selector = 'div[data-theme-tiles="1"]';

api.decorateCooked($elem =>
	$elem
		.children(selector)
		// do your work here for example:
		.imagesLoaded(function() {
			$(selector).masonry({
				itemSelector: ".lightbox-wrapper"
			});
		})
);

And it just works! no excessive firing, no bloat. Amazing! :fire::fire:


So, to recap all the stuff from earlier: (from my basic understanding which maybe off)

This will work if you want something done when topic pages are opened:

const TopicRoute = require("discourse/routes/topic").default;

TopicRoute.reopen({
	activate: function() {
		this._super();
		Em.run.next(function() {
			// do stuff here when a topic page is opend
		});
	}
});

And you can do stuff HOWEVER, you wont be able to modify the contents of the topic because they are in virtual dom and that’s why jQuery was not able to modify the topic contents while it was able to do stuff like console.log and modify parts of the pre-existing actual dom like this:

const TopicRoute = require("discourse/routes/topic").default;

TopicRoute.reopen({
	activate: function() {
		this._super();
		Em.run.next(function() {
			console.log("topic page opened");
			$("body").css(
				"background-color",
				"#" + ((Math.random() * 0xffffff) << 0).toString(16)
			);
		});
	}
});

In the same way, this can be used to make changes when the user leaves a topic page:

const TopicRoute = require("discourse/routes/topic").default;

TopicRoute.reopen({
	deactivate: function() {
		this._super();
		console.log("topic page closed");
		// do more stuff here or a bit of cleaning up
	}
});

Again you can do whatever you need here because the user will be leaving the topic and so you would not be modifying the virtual dom contents of the topic anyways.

Moreover;

api.onPageChange(url => {
	// do stuff here
});

Will also work on topic pages however, the same from above will still apply. You cannot modify the actual contents of the topic (again, they are in virtual dom) but you can modify elements in the pre-existing dom.

So this would work, even on topic pages:

api.onPageChange(url => {
	$("body").css(
		"background-color",
		"#" + ((Math.random() * 0xffffff) << 0).toString(16)
	);
});

Once I get a firmer grip on this I will probably create a how-to topic with the relevant bits

Thanks again @vinothkannans :sunflower:

14 Likes