What is the best way to inject JavaScript code?

(Manthan Mallikarjun) #1

Right now I am trying to get JS to inject HTML into each page.

I am using $(document).ready(function(){} but it only works when you refresh the page. If you go to the homepage and click on a topic, the HTML doesnt get injected.

Im not sure which event to inject the JS after.

Phonegap SPA app for Apple and Google store
(Mittineague) #2

That seems like a major security vulnerability waiting to happen.

Are you sure you can’t do what you need another way?

(lid) #3

I am not sure if there is a best way to inject JavaScript code, is it depends on what you need and the application logic.

Discourse is a one page beast, navigation is virtual and evolve around dynamic content loading ( see the ember.js framework).

This is why you are getting domready callback once only on the first load of the page.

you will need to understand two things first

  1. ember.js
  2. discourse logic
  3. what you trying to do

I am going to give you a snippet of code that can point you in the right direction.

be carful using this code without testing I suspect that it might cause bugs, so use it as a general reference of a concept

  didInsertElement : function(){
    Ember.run.scheduleOnce('afterRender', this, this.afterRenderEvent);
  afterRenderEvent : function(){
   console.log ("Topic just got rendered");

@Mittineague running js is not security risk, what you are running and the source of what you are running can be.

Good luck


I was able to do the successful a few times. But as soon as you trip up the native discourse JS things go all pear shaped. If you visit my site today (on my profile page upper right hand corner if you are viewing on a desktop/laptop) and then view the source…you can see that I was adding some JS and the page loads but nothing displays. Turning JS off would be wonderful to have as a troubleshooting alternative but the Admin section is dependant on it to function. So you risk a lot if your script is untested or dependencies collide.

I’ll keep trying to expand discourse with the head content section but it will always be touch and go.

(Manthan Mallikarjun) #5

I am actually just placing an advertisement. It goes underneath the OP and above the second post. Here is how it looks.

I am just having a little trouble getting it to show 100% of the time.

(Manthan Mallikarjun) #6


Thanks for the info. Since my JS is very easy and doesnt effect much, I think it will work fine.

BTW your site wont load for me :frowning:.

(Manthan Mallikarjun) #7

Thanks for this. Im not sure exactly how this code works, but I will figure it out. Thanks.

(lid) #8

for start you can run it in console, after you run it,whenever you navigate to a topic you will see a trace message in console
"Topic just got rendered", and it should run once for topic load as far as i can tell

how you integrate it in your code … you will have to figure it out :smile:

(Wint) #9
  didInsertElement : function(){
    Ember.run.scheduleOnce('afterRender', this, this.afterRenderEvent);
  afterRenderEvent : function(){
   console.log ("Topic just got rendered");

Could a person use this if you wanted a script to run in every topic? I’ve wanted to add tooltip text since see here but I’ve never been able to get it working properly.

Edited to add it seems to work when I add it to the Header in customization as long as the refresh in the browser is then clicked. Going to test and see if this works everywhere.

Second Edit: yeah still doesn’t work, if I click on another category, then back into the topic, the script isn’t run. Might have to see if this works if I can figure out how to change this. Found my original question on this subject. Discourse Meta

(Manthan Mallikarjun) #10

@Lid Yep. It doesnt work 100% of the time as @Wint mentioned.

(Wint) #11

I was looking at plugins and seeing if that would be a good approach. It would be nice to have a setting in the admin console but I recognize this is probably a fringe case. A plugin seems like an alternative solution to actually changing discourse itself.

I’m trying to figure out how to do it with a plugin now, if I figure it out I’ll let you know.

(Manthan Mallikarjun) #12

A plugin would be too complicated for what I am doing. Im literally just injecting an image. I also dont know much Ruby so plugins would be somewhat hard for me.

Anyways, good luck!

(lid) #13

As I said this code snippet is a gust of wind in a possible direction. It is not a complete solution. To have a complete solution you will have to understand what is going on at the core on work its quirks.

Good luck with the plugin approach.

I wonder if injecting content can potentially have bad impact on the parts of code the rely on post positioning. But cross that bridge when you get there.

(Wint) #14

I know next to nothing in Ruby, but this seems like a good time to learn. If you’re curious, this is the guide I’m starting with:


(Sam Saffron) #15

That post is out of date and should be avoided

@danneu can we either pull that blog post, or put a big notice on top saying it is out of date, people keep finding it

(lid) #17

@Wint testing my code here on meta, I am getting the trace message on every topic, even if I go to another category. could be that you are not seeing the trace possibly because google sometimes aggregate the message, and add a counter next to it.
you can try replacing the trace with a

 alert("topic render")" ```

 then you are not going to miss it.

(Manthan Mallikarjun) #18

You are right, BUT some of the code doesnt execute. I have some code just above the console.log that I want to run. Whenever I click on the topic, it gets logged to the console, but the other code doesnt execute.

(Wint) #19

Any guides that are up to date or is there nothing yet?

(lid) #20

I guess what you trying to do rely on other DOM elements that may not be ready at that particular moment.
I think this is where a deeper understanding of the way discourse work and its internals is needed.

You can try explore or wait for guides and plugins. like @Wint

(Manthan Mallikarjun) #21

Oh, you are right! I am waiting for the posts to load.


@Wint ^^^