bernhard Posted September 27, 2018 Share Posted September 27, 2018 Hey! Something that has annoyed me several times already over time. I have this line in one of my modules: config()->scripts->add(config()->urls->siteModules . 'RockCRM/scripts/createInvoiceButton.js'); The line of code is placed in one module inside folder /site/modules/RockCRM, so what I tried first was config()->scripts->add(__DIR__ . '/scripts/createInvoiceButton.js'); But this throws an error that it is not allowed to add resources like this. I really want to get rid of the 'config()->urls->siteModules . 'RockCRM'' part! Is there any native function to add scripts via path (not via relative url)? Or is there a way to get the relative url of a module? I don't want to add the filename or module's name manually - hey, I'm already in that file, so that should really be easier, quicker and more future proof (thing of renaming the module one day...). I've built some helper functions in the past to do that, but they are spread wildly and implemented differently. I want to get one standard approach. I thought of submitting a PR to make the scripts take absolute paths as well, but I only want to do that if you guys don't know of an existing and good solution. Thanks for your help! Link to comment Share on other sites More sharing options...
Soma Posted September 27, 2018 Share Posted September 27, 2018 config()->scripts->add(config()->urls->RockCRM . 'scripts/createInvoiceButton.js'); 3 Link to comment Share on other sites More sharing options...
Soma Posted September 27, 2018 Share Posted September 27, 2018 Or you can even use the class name too config()->scripts->add(config()->urls->{$this->className} . 'scripts/createInvoiceButton.js'); 3 1 Link to comment Share on other sites More sharing options...
bernhard Posted September 27, 2018 Author Share Posted September 27, 2018 On 9/27/2018 at 3:27 PM, Soma said: config()->scripts->add(config()->urls->{$this->className} . 'scripts/createInvoiceButton.js'); great! thx soma! this is also possible and imho the cleanest solution: config()->scripts->add(config()->urls($this) . 'scripts/test.js'); thx ? 3 1 Link to comment Share on other sites More sharing options...
adrian Posted September 28, 2018 Share Posted September 28, 2018 You don't even need className config()->urls->$this . 'scripts/test.js'; 3 Link to comment Share on other sites More sharing options...
adrian Posted September 28, 2018 Share Posted September 28, 2018 Or if you are only supporting recent'ish versions of PW: urls()->$this . 'script/test.js'; 2 1 Link to comment Share on other sites More sharing options...
bernhard Posted September 28, 2018 Author Share Posted September 28, 2018 Crazy, thank you Adrian! How do you know that? I think maybe I can improve how to read the docs or code. I had a look both in the API docs and in the code directly but didn't find this option... Link to comment Share on other sites More sharing options...
adrian Posted September 28, 2018 Share Posted September 28, 2018 It's not linked to but: http://processwire.com/api/ref/urls/ I learned about this from a blog post: https://processwire.com/blog/posts/processwire-3.0.40-core-updates/#urls-and-paths Pity the docs are hidden. Also a shame there's no $paths equivalent. 2 Link to comment Share on other sites More sharing options...
bernhard Posted September 28, 2018 Author Share Posted September 28, 2018 Great, thanks! Now that I'm using the functions API all the time I'll also use inputGet('myvar', 'integer') more ? very short but also verbose enough imho ? Link to comment Share on other sites More sharing options...
Soma Posted September 28, 2018 Share Posted September 28, 2018 6 hours ago, adrian said: You don't even need className config()->urls->$this . 'scripts/test.js'; Just want to note that in case of multi-instance usage $this->wire("config")->paths->templates != config()->paths->templates So in modules developement you should avoid using function API. 3 Link to comment Share on other sites More sharing options...
adrian Posted September 28, 2018 Share Posted September 28, 2018 7 hours ago, Soma said: So in modules developement you should avoid using function API. I completely agree. The functions API may not even be turned on for the user's PW install. That said, you could still use: $this->wire('config')->urs->$this as the safest short URL. 1 Link to comment Share on other sites More sharing options...
bernhard Posted September 29, 2018 Author Share Posted September 29, 2018 Thank you for the discussion, really appreciate it! What about this? urls($this); // using functions api $this->urls($this); // without functions api and multi-instance proof I guess this is about as short as it can get ? The initial example would get: // from this config()->scripts->add(config()->urls->siteModules . 'RockCRM/scripts/createInvoiceButton.js'); // to that config()->scripts->add(urls($this) . 'scripts/createInvoiceButton.js'); 23 hours ago, Soma said: Just want to note that in case of multi-instance usage Thank you soma for that hint. That's a real drawback, even if I've never worked with multi-instance so far. But I think it would be the best to already take care of that in my daily work. Unfortunately I totally lose intellisense in my IDE if i use $this->urls() instead of urls() ? Does anybody know if I can do something about that? Then it would be perfect ? Link to comment Share on other sites More sharing options...
bernhard Posted September 29, 2018 Author Share Posted September 29, 2018 Ok... I did some more testing and I think it's better not to use the functions api at all in module development. It's a level of lazyness that is not good IMHO and could lead to severe problems/drawbacks in the future (when using the module in a multi instance environment). Thank you @Soma for that veto! 5 hours ago, bernhard said: Unfortunately I totally lose intellisense in my IDE if i use $this->urls() instead of urls() ? That statement was actually wrong! I get proper suggestions when I stick to proper syntax and don't use shortcuts. I think that is a good practise as it is more verbose to newcomers (I have always liked reading other's code and how easy to understand PW's api is) and also reflects the internal PW structure better than plain functioncalls (wordpress is calling...). So my (currently ? ) final version is: $this->config->scripts->add($this->config->urls($this) . 'scripts/createInvoiceButton.js'); Link to comment Share on other sites More sharing options...
adrian Posted September 29, 2018 Share Posted September 29, 2018 For module development you should actually use: $this->wire('config')->scripts->add($this->wire('config')->urls->$this Take a look at Ryan's Github repo (https://github.com/ryancramerdesign/) for his most recent modules and you'll see that is the approach he takes. @LostKobrakai has an excellent post on when it's ok use: $config vs $this->config vs $this->wire('config') but I can't find it right now. 1 1 Link to comment Share on other sites More sharing options...
bernhard Posted September 29, 2018 Author Share Posted September 29, 2018 Thx again! For proper code completion I'd prefer $this->wire->scripts instead of $this->wire('scripts') - would that also be ok? Link to comment Share on other sites More sharing options...
adrian Posted September 29, 2018 Share Posted September 29, 2018 4 minutes ago, bernhard said: I'd prefer $this->wire->scripts instead of $this->wire('scripts') - would that also be ok? I think so, although typically I see: $this->wire()->scripts rather than $this->wire->scripts although I don't honestly know if it makes a difference. OT, but note that in the Console, I need to use $module instead of $this for the name of the module, but otherwise you can test all these options there. 1 Link to comment Share on other sites More sharing options...
Robin S Posted September 29, 2018 Share Posted September 29, 2018 Besides the multi-instance thing, Ryan brought to my attention recently another reason to prefer $this->wire('config') or $this->wire()->config over $this->config... If you are doing this inside a class (e.g. a module) then it's less efficient to do $this->config because PW has to first check to see if you have a property or method in the class named config, and only after that go to the $config API variable. With $this->wire('config') or $this->wire()->config there is no uncertainty. Personally I prefer $this->wire()->config over $this->wire('config'), only because it's easier to paste it in or do a find/replace when updating older code, and easier to assign a shortcut to $this->wire()-> in my IDE and have my cursor end up in the right place after I've typed the API variable name. ? 2 Link to comment Share on other sites More sharing options...
adrian Posted September 30, 2018 Share Posted September 30, 2018 On 9/28/2018 at 6:46 PM, adrian said: It's not linked to but: http://processwire.com/api/ref/urls/ Just an FYI on this front - $urls is linked to from the API Variables section of the Tracy PW Info panel. It is always up to date because it makes use of: $this->wire('all') to get all available variables. 3 Link to comment Share on other sites More sharing options...
LostKobrakai Posted September 30, 2018 Share Posted September 30, 2018 18 hours ago, adrian said: @LostKobrakai has an excellent post on when it's ok use: $config vs $this->config vs $this->wire('config') but I can't find it right now. or that one But I had so search a bit as well. 1 1 Link to comment Share on other sites More sharing options...
Recommended Posts