Jump to content

gebeer

Members
  • Posts

    1,393
  • Joined

  • Last visited

  • Days Won

    39

Posts posted by gebeer

  1. I definitely would encourage you to give PW a try. Most people who took the initial effort are now very happy PW developers :)

    You might want to jump right in and have some good reads.

    Categorizing content tutorial

    Example code for creating a form with file upload

    If creating frontend forms through the API is over your head at the moment, you could always use the very affordable paid extension form builder. Easy to use and a big time saver. 

    Multi language

    And learning PHP when working with PW can be fun. Don't worry, you fill find tons of helpful posts in the forum and the friendly community will help you get started.

    • Like 2
  2. I think the context may be wrong. I don't know Joomla at all, but, to me, site:create would imply a multi-site environment, especially considering the existence of site:delete. Or am I wrong?

    In the joomla-vagrant context it makes perfect sense because with that command you can setup a new site in a subdomain so you can have multiple dev sites residing in one virtual machine. But I see your point when considering multi site environments.

  3. Thank you for putting this together. This is absolutely great :)

    I came over from Joomla some time ago and one of the many joomla devs have created joomla-console. They combine it with their joomla-vagrant box which is a great tool for development. I am actually still using it for quick setup of PW projects  ;) And I've been thinking for quite some time how great it would be to have a console tool for PW. And now it is here. So big thumbs up!

    I see that there is some kind of naming convention for commands now. Have you ever considered renaming the 'new' to 'site:create' Thats what joomla-console uses and they also have a 'site:delete'.

  4. I knew that this would cause conflict because there are so many different ways of implementing script loading. So your comments on this are more then welcome.

    I read and revived this discussion about how to best approach script inclusion when developing a module. And chose a mixed approach because I'm really not sure myself how to best do it and to experiment with different methods.

    The original approach of the Google Maps module just didn't seem perfect since it forces users to include stuff in the head. So what to do as a user if you don't want to have scripts in <head>. But then I guess there is no perfect way.

    Main reason for injecting the "inline script" at the very end: wanted to make sure that scripts get loaded in the right order.

    @Soma

    why wouldn't you want to have it before </body>?


    @Wanze

    thanks for clarifying the terminology. I'm quite new to PW module development. So I really appreciate any input that I can learn from.

    • Like 1
  5. Solved this way:

    I made an additional autoload module 'MarkupAddInlineScript' to execute the hook.

    In the render() method of the map markup module I assign my inline script string to the page object

    $this->page->inlineScript = $inlineScript; 

    Now in init() of MarkupAddInlineScript I execute the hook

    $this->addHookAfter('Page::render', $this, 'addInlineScript'); 

    that calls my hook method

    	public function addInlineScript($event) {
    
    		$page = $event->object;
    
    		if ($page->inlineScript) {
    
    			$event->return = str_replace("</body>", $page->inlineScript . "</body>", $event->return);
    
    		}
    
    	}
     

    My hook method only executes when $page->inlineScript returns a value other then null. This will happen only on pages that instantiate a map object with $map = $modules->get('MarkupLeafletMap'); 

    As a result I have the script that was previously insertet inline on the page, neatly attached to the end of my page body

    <script type="text/javascript">...</script>
    </body> 

    All other scripts that are required for rendering the map are also attached at the end of the body before the "inline script" through $config->scripts->add() in the init() method of the 'MarkupLeafletMap' module.

    Now when people install this module, they don't have to worry about including the various scripts themselves in the head or body and I can be sure that they get executed in the right order, too. 

    Only thing users of the module need to do now is include 

    <?php foreach($config->scripts as $url) echo "<script src='$url'></script>"; ?> 

    before </body>

  6. Thank you all for the insights on how hooks are working. This really helps me to better understand what is going on.

    @Wanze

    but then you must be sure that "registering" the hook happens before Pw executes the hooked method.

    How would I approach that? My guess is that it needs to happen during init() of my module, am I right?

  7. I reinstalled the module to make PW know that it is not autoload anymore.

    Now $this->addHookAfter('Page::render', $this, 'addInlineScript'); is not executed anymore. Doesn't matter whether I call it from init() or render()

    This confirms for me that modules need to be autoload in order to place hooks in them, like the wiki suggests.

    I guess I need to find another way of implementing my logic...

    But thanks again for your help.

  8. Thank ou for the quick reply.

    Maybe there is some misunderstanding here.

    I don't want to make a function ___hookable that is part of my module. I want to add an after hook to Page::render where I call my method 'addInlineScript':

    $page->addHookAfter('render', $this, 'addInlineScript');
    

    This hook call I placed inside the render() method of my module.

    In the meantime I found out that the hook gets called when I place it in init() method of my module.

    But I don't want to call it from init() because the 'addInlineScript' method depends on some property that is created in render(). So I need to call the hook from there.

    The exit() is just there to confirm that my method gets called.

    I don't want the module to be autoload. I just understood from the wiki that it needs to be autoload in order to call a hook from within it. But I guess I got this wrong.

    So I made the module none autoload again but it is still being loaded. Has this to do with module cache and how can I make it not autoload again? 

  9. Hello,

    I have a hook in a custom method of a non autoload module and it is not calling my hook method.

    In the wiki I read 

    Modules that are intended to attach hooks in the application typically should be autoload because they listen in to classes rather than have classes call upon them. If they weren't autoload, then they might never get to attach their hooks.
    

    Does this mean that hooks are only working in autoload modules?

    I added 'singular' => true and  'autoload' => true to getModuleInfo() but still my hook funktion does not get called.

    My hook call at the end of this render method

    $this->inlineScript = $inlineScript;
    
    $page->addHookAfter('render', $this, 'addInlineScript'); 

    $page object is available. Also tried $this->addHookAfter('Page::render', $this, 'addInlineScript');

    and my hook method

    	public function addInlineScript($event) {
    		exit("gbr");
    		// $value contains the full rendered markup of a $page 
    		$value  = $event->return; 
    
    		$value = str_replace("</body>", $this->inlineScript . "</body>", $value);
    		// set the modified value back to the return value 
    		$event->return = $value; 
    	}
     

    Why is this not working? Any help would be much appreciated.

  10. I think the providers can be a part of the module as long as one can choose from others providers like Mapbox.

    I agree. Added all available providers to the select dropdown and have set OpenStreetMap.Mapnik as default.

    Will post the next days with update on awesome icons...

    • Like 2
  11. When developers want to use your module it's not bad they are following your instructions to make it work.

    That's true.

    But if your instruction go something like: "You need to include these 4 scripts in your head tag to make this module work and you need to download them from these 4 different places first", it may drive people off.

    Imagine a developer who cares about page loading optimization and he cannot do it right because of your module. Or he has to go and alter the module code so it fits his needs.

    Wouldn't it be better if the module followed commonly accepted best practices and people who use the module don't need to care about things like manual script inclusion?

    I personally don't feel really comfortable with the proposed approach 3, too. The $this->config->scripts->add() method seems to be the preferable way to go.

    But then you need to instruct the users of your module to include the necessary php for rendering the scripts tags before </body>. Which I consider to be a PW best practice anyway when it comes to conditional loading of scripts.

    The only point that I really wanted to make is that we should follow best practices and include our scripts at the end of the page and not in the head. If this limits developers freedom, it at least forces something on them that is generally a good thing.

  12. I came across this thread while working on my first PW module that needs to load quite a lot of scripts. So I am going to revive this thread because the OP makes an important point here: how to best find the balance between easy module integration and freedom for PW users when it comes to template structure . 

    In my opinion, best practices for script inclusion should also be considered here. So while giving users the most possible freedom in how to structure their templates, they should at the same time be made aware of ways how to best implement script loading. Not only with PW, but in general.

    I for myself am still learning a lot about web development best practices while developing sites with PW. There is a lot of useful information to be found here in the forums which is absolutely great.

    One thing that most of web devs seem to agree upon is that loading scripts at the end of your template just before </body> increases site loading speed and thus user experience. Besides that it also makes sure that the DOM is already available to those scripts.

    And here lies the culprit of approach 3 proposed by the OP: all additional scripts get loaded in the <head> which slows down page loading time.

    Thus I would implement the addScripts method like this

    public function addScripts($event) {
    		$page = $event->object; 
    
    		// don't add this to the admin pages
    		if($page->template == 'admin') return;
    
                   //other mechanisms to ensure the script only loads when this module was called in the front-end
          
          $additionalScripts = '[myScripts...]';
    
    		$event->return = str_replace("</body>", $additionalHeadScripts.'</body>', $event->return); 
    	}
    

    Only drawback  I can see: following this approach, the module developer has to make sure that all inline scripts wait for the scripts they depend upon before they are executed (eg with $(window).load or $(document).ready)

  13. Thanks again for the port to leaflet! I prefer OSM over google maps and have been using it for quite some time. Leaflet is very powerful and opens up many possibilities.

    I forked Mats' module and added support for leaflet-providers so we can choose different map tile providers (see my post here). It is still a work in progress but seems stable. Once it is ready for production I'll make a pull request.

    Mats, do you think we should use leaflet-providers as standard or offer the user a choice whether they want to use it or not?

    Next up I will add an icon field and support for Leaflet.awesome-markers.

    • Like 8
  14. @Mats

    thank you so much for your OSM version of the module. Have you opened a thread dedicated to it, yet? Couldn't find it in the forums.

    I forked your module and added basic support for leaflet-providers. In the field settings we can now choose the map tile provider.

    post-1920-0-17713500-1429776568_thumb.pn

    and the map renders accordingly

    (example with MapQuest.Open)

    post-1920-0-39407600-1429776974_thumb.pn

    (example with OpenStreetMap.BlackAndWhite)

    post-1920-0-87065700-1429776994_thumb.pn

    I'm thinking adding this on a per marker basis also but I'm not quite sure yet if it makes sense at all to define tiles per marker?

    We should definitely open a separate thread for your module, what do you think?

    • Like 3
  15. How can I access $defaultMarkup from within my hook:

    	public function init() {
    		$this->addHookBefore('Page::render', $this, 'addTooltipJS'); 
    		$this->addHookBefore('InputfieldWrapper::render', $this, 'addTooltip'); 
    	}
    	
    	public function addTooltip(HookEvent $event) {
    		$defaultMarkup =  ;
    
    		$event->return;
    	}
    
    
  16. I have searched the forum and google but couldn't find anything related.

    I want to show all field descriptions in admin forms as tooltips. Has this request really not come up before?

    I imagine a module that hooks into the Inputfield class, adds the description as title value to the inputfield and then makes use of https://jqueryui.com/tooltip/.

    Am I on the right track here?

    EDIT:

    I made a module "InputfieldHookAddTitle":

    <?php
    
    class InputfieldHookAddTitle extends WireData implements Module {
    
    	public static function getModuleInfo() {	
    		return array(
    			'title' => 'Inputfield Hook Add Title',
    			'version' => 100,
    			'summary' => 'Adds title attribute to inputfields with field description as value',
    			'singular' => true,
    			'autoload' => true,
    			);
    	}
    	
    	public function init() {
    		$this->addHookBefore('Inputfield::render', $this, 'addTitle'); 
    	}
    	
    	public function addTitle(HookEvent $event) {
    		$inputfield = $event->object;
    
    		if ($inputfield->description == "") return;
    		
    		$inputfield->setAttribute('title', $inputfield->description);
    
    		$event->return;
    	}
    	
    }
    

    This adds title attribute with value description to inputfields.

    Now I need to get rid of the original <p class="description"> tag which is set in the constructor method. How would I unset this? I don't see a unset method.

    And how do I add the Jquery tooltip js?

    EDIT:

    I managed to add the custom JS to the admin pages, thanks to Soma's blog post.

    In my site/templates/admin.php I added:

    // add tooltip JS to admin pages
    $modules->get('JqueryCore');
    $modules->get('JqueryUI');
    $config->scripts->add($config->urls->templates . "js/admintooltips.js");
    
    

    and the admintooltips.js

    $(function() {
        var tooltips = $( "[title]" ).tooltip({
          position: {
            my: "left top",
            at: "right+5 top-5"
          }
        });
    });
    

    Now I only need to get rid of the original description. Any pointers would be much appreciated.

    • Like 1
×
×
  • Create New...