How to grab Topic/Category information from the frontend


(Jordan Nunez) #1

I am adding some custom Mixpanel tracking to our discourse implementation.

Currently, I am using Discourse.PageTracker.current() to add an on(“click”) listener on user click through. This is great and I can identify when a category or topic is loaded. However, is there a way I can grab the topic/category model data from the loaded ajax request. In other words, Can I call something like Discourse.model to get a object of the Topic Name and Author?

I am only using js injection via admin > customize > CSS/HTML. So I wont be doing anything from the back end. I could use jQuery to grab the data that is produces on the page. However, I would prefer something less hacky if possible.

Thanks and advance!


(Dean Taylor) #2

Is the page title sufficient? It’s updated too.

Just thinking it would be super simple if it was.


(Jordan Nunez) #3

It does, but it comes out something like

Latest Getting started topics - Company Community

So this would require something like:

title.split("-")[0].split(" ")…

I would much rather prefer if I can sneak into the stored model that rendered the page :stuck_out_tongue:

any suggestions? BTW thanks for the fast reply :slight_smile:


(Dean Taylor) #4

I know it’s possible.

I’m sure somebody else here will get you a reply with a solution before I’m in front of a computer again.

###EDIT - 20 hours later
I’m not saying this is great code - one of the Discourse team will likely have better ways of doing this…

… written to just give you an idea of how to get to some basic info about a category or topic (i.e. name)

<script>
if (window.jQuery) {
    window.jQuery(function ($) {
        var PageTracker = require('discourse/lib/page-tracker').default,       
          updateTracking = function () {
            var app = Discourse.__container__.lookup('route:application'),
              	routeName = app.controller.currentRouteName,
              	routeBaseName = routeName.split('.')[0],
              	routeTail,
              	category,
              	output = [];
          	
            switch (routeBaseName) {
              case 'topic':
              	output.push('topic', app.modelFor('topic').title);
              	break;
              case 'discovery':
              	routeTail = routeName.split('.')[1];
              	if (routeTail.indexOf('category') === 0 || routeTail.indexOf('Category') !== -1) {
              		output.push('category', routeTail);
              		category = app.controllerFor('discovery/topics').get('category');
              		if (category.parentCategory) {
              			output.push(category.parentCategory.name);
              		}
              		output.push(category.name);
              	} else {
              		output.push('unknown discovery', routeName);
              	}
              	break;
              default:
              	output.push('unknown route', routeName);
              }
              console.log('Tracked', output.join('||'));
          };
        	
        
        
        
            PageTracker.current().on('change', function (url) {
            setTimeout(function () {
                updateTracking();
            }, 100);
        });
    });
}
</script>

Here is some sample output in the developers console:

Tracked unknown discovery||discovery.new
Tracked unknown discovery||discovery.latest
Tracked unknown route||userActivity.bookmarks
Tracked unknown discovery||discovery.latest
Tracked topic||Best way to create an interface for templates?
Tracked category||parentCategory||dev
Tracked category||parentCategory||howto
Tracked category||category||howto||tips & tricks
Tracked category||newCategory||howto||tips & tricks
Tracked category||unreadCategory||howto||tips & tricks
Tracked topic||Dark theme with block posts
Tracked topic||Dark Material Design

Hope this pushes you forward.


Mixpanel Integration or Plugin?
(Jordan Nunez) #5

Thanks @DeanMarkTaylor; much appreciated. I will poke around with this approach. I may come back at you with more questions. :slight_smile: