Is anyone good with Javascript? I need a hand

Here’s the problem: the #community-repair category is a bit of a mess when viewed normally (like this) - there’s a confusing mix of languages and it’s hard to find things because discussions from the different subcategories are displayed by default.

It would be much neater if discussions from subcategories weren’t displayed by default (like this). There’s no setting for this yet in Discourse, so I’ve been using Javascript as a workaround. It appends /none to category links on the homepage:

// set 'none' as default view on category page to hide posts from subcategories
$(document).ready(function() {
        // do it only once
        $('td.category .ember-view a').each(function() {
            if ($(this).hasClass('link-fixed')) {
                return;
            }
            // do it only if there's subcategories
            if ($(this).parents('td.category').find('div.subcategories').length) {
                var link = $(this).prop('href');
                $(this).prop('href', link+'/none');
            }
            
            $(this).addClass('link-fixed');
        });
    });

This works well until you navigate back to the homepage by clicking on the ‘Restarters logo’. After doing that, the code no longer works.

My Javascript skills aren’t good enough to know why this is happening. Does anyone have any ideas?

Perhaps @hkoundi can help? :laptop:

1 Like

I think it is probably as Discourse is using Ember and it’s functioning as a single page application, so jQuery’s document.ready will only get triggered once, on the first full page load. Hence why it works consistently if you refresh in the browser. But when you navigate to a category and come back within the app, Ember will be resetting the URLs again without refreshing the page, so document.ready won’t trigger as it’s not a full page load, and your function won’t be called to append to the category URLs.

I think you would need an event handler that taps into Ember’s event system somehow. I’ve never used Ember so don’t know off the top of my head!

Something like this should work, although it’s a bit of a blunt instrument in that it will fire on every page change. Ideally we would want to find a way to only run it on the homepage (perhaps using the url that’s passed in onPageChange.)

<script type="text/discourse-plugin" version="0.4">
api.onPageChange((url, title) => {

    // This is your existing code
    $('td.category .ember-view a').each(function() {
        if ($(this).hasClass('link-fixed')) {
            return;
        }
        // do it only if there's subcategories
        if ($(this).parents('td.category').find('div.subcategories').length) {
            var link = $(this).prop('href');
            $(this).prop('href', link+'/none');
        }
            
        $(this).addClass('link-fixed');
    });

});
</script>

Would also be better to put it before </body> rather than </head>.

Hello

Yes sure I can have a look maybe tonight most likely this weekend.

Cheers

Halima

Thanks @neil, that was my thought too, but I’m a complete ember n00b! Good to know there’s a PageChange hook - sounds like a good start.

@hkoundi - thanks for offering to help! Do you have any experience with ember or how we could use the PageChange mechanism to set up a more reliable script?

hi @james I do not have experience with ember per say, but I have done some JS and JQuery and I believe should be working similarly. Is this still a problem btw? (the subcategory display issue)
Sorry I am catching up on all the things I said I would do :sweat_smile:

No worries @hkoundi! Thanks for offering!
yep, it’s still an issue - the current fix only works the first time the application is loaded (or refreshed). Any ideas you have would be super welcome!

Hi @james,

Apart from trying what @neil suggested and hooking into the page change event, I can see that when the user clicks on the restart home page from the link on the category page, a call to ‘https://talk.restarters.net/categories_and_latest?_=1533593576099’ is made.
Do you have a mean to change this so the response has the slug with the ‘/none’ in it when subcategory_ids.size > 0 :

"category_list": {
		"can_create_category": false,
		"categories": [{
			"id": 5,
			"name": "Repair in your community",
			"slug": "community-repair",
			"topic_count": 3,
			"subcategory_ids": [7, 9, 14, 10],
			"uploaded_background": null,
                       .....
		}, .... ]

Great question @hkoundi! I know we can’t access the core ember code, but I’m not sure how/whether we can overwrite it with JS (this goes significantly beyond my current Javascript skills! :sweat_smile: )

I’ll need to do some research on both of those potential solutions (to work out how to do it)

Hey @james, is the discourse source code somewhere in a repo I can look at? (something like github)

Yep! Here it is:

What do you mean ours or the generic @hkoundi

Hi @james, @Janet

I meant the restart project one, is it on the same repo I was added to? I suppose I could just search there :slight_smile:

@hkoundi, ah sorry!
The core code for our instance of Discourse will be the same as in the main repository above - we’re using vanilla Discourse with some (largely cosmetic) changes. That said, we can’t change the core ember code as we’re on a hosted plan.

Got an interesting response to my query about this on the main Discourse forum. But I’m not quite sure how to do what this person suggests (if it’s even possible without having access to the source code):

I’m guessing you can’t get at that ruby code. Maybe you can add JS that tries to detect a back and forces a reload? See the self-answer here https://stackoverflow.com/questions/31143480/javascript-back-button-event

2 Likes

Worth exploring, cheers Ian!

That’s correct, we’re not self-hosting Discourse so we can’t tweak any of the underlying Ruby (as far as I know at least…)