Jump to content

jploch

Members
  • Posts

    347
  • Joined

  • Last visited

  • Days Won

    8

Posts posted by jploch

  1. 5 minutes ago, kongondo said:

    Then Alpine JS it is ?. Learn Vue, say thanks to the creators then say hello to Alpine JS. You will write its code right inside your ProcessWire inputfields, markup, whatever. Everything will be reactive.

    Nice! Thanks for the suggestion. Alpine looks great. I will definitely check out vue und alpine. There is a lot of new stuff to learn, working mainly with jquery in the past. This might also be a little to late for my pagebuilder module Iam currently working on (almost done, it's written in jQuery und uses the change event on the inputfields). However refactoring that, might be a nice way to learn about these reactive js frameworks ?

    • Like 1
  2. I managed to get it working. 
    However for my module it would be nice to use PW to render some inputfields und use them together with vue. But what I have learned so far is that vue would be used to render the markup, so I would need to write the markup for the inputfields myself und put them in my js file? That would not be ideal, because the markup might change with new admin themes. Is there a way to use PWs API to create the inputfields and use vue to react to the user input? 

  3. @kongondo
    I would love to try vue for module development, but have trouble getting it to work. A tutorial would be highly appreciated! A vue module boilerplate would be nice ? 

    I just started experimenting with vue, it looks very promising! Would it still be possible to run the module from within PW (when developing)? From what I understand vue uses it's own development server?

    • Like 1
  4. Today I used this module for the first time to implement an RSS feed into an exiting website.
    On my local dev enviroment, everything worked well. But on the live website I get a error, when umlaute (ä,ö,ü) are present in the title field. The error looks like this:

    This page contains the following errors:
    error on line 4 at column 51: Entity 'uuml' not defined
    Below is a rendering of the page up to the first error.

    Here is the code to render the RSS feed (if I comment out the part $rss->title and $rss->description, it works)

    <?php namespace ProcessWire;
    
    // retrieve the RSS module
    $rss = $modules->get("MarkupRSS");
    
    // configure the feed. see the actual module file for more optional config options.
    $rss->title = "ATLAS ist das Kundenmagazin von Gebrüder Weiss";
    $rss->description = "ATLAS ist das Kundenmagazin von Gebrüder Weiss.";
    $rss->itemDescriptionField = 'textarea';
    
    // find the pages you want to appear in the feed.
    // this can be any group of pages returned by $pages->find() or $page->children(), etc.
    $items = $pages->find("template=artikel, limit=10, sort=-parent, sort=sort");
    
    // send the output of the RSS feed, and you are done
    $rss->render($items);
    ?>

    EDIT:
    My local PW version is 3.0.150 and my live PW version is 3.0.165.
    After replacing the module file (MarkupRSS.module) from the live site with the older version from my local site, everything is working fine. So there seems to be an issue with the newer version.

  5. still it would be nice to just use the title field as the block id without the need for an additional custom field. The title is not really needed in the context of the block, so I could just hide it in the editor. Since the block pages are hidden under the admin page in the tree (this can be changed in field settings, but maybe I will remove that setting and make that the default), there is no real danger to acidentally change the title of a block manually. That way I don't have to take care of installing/uninstalling the custom field.

    I guess the main question is if it should be possible to add existing pages to my grid, that do not use the block templates but are just regular pages in the tree. For those cases the title field would not be a good option. However it would still be possible to include those pages with a block that has a page reference field. This would also be a better option to include existing pages, since it's much more clear there is an actual connection to another page. 

  6. 1 hour ago, d'Hinnisdaël said:

    What's the reasoning behind storing the data on the parent and not on the children?

    I tried to keep it simple and was also concerned with performance. Updating the JSON field on the parent page is easy. Storing the data on the children/blocks would mean I have to update the JSON via ajax every time the blocks style is updated (not a big deal). Also there are some settings for the parent page I need to save as well, so it seemed like a good approach to have just one JSON field to keep all the data in one place. Maybe I will consider moving the JSON to each block instead, but that would mean a lot of refactoring needs to be done. Also what will happen if the same block page is added to two different grid fields/parent pages, then it could only have one style that is associated with the block. With my current approach, it would be possible to have different styles for the same block, since the JSON is stored on the parent. I have to think about this a little.

    Thanks for looking into this! I have a tunnel vision by now, and there are so many things to consider, it's very helpful to get a fresh perspective on it.

  7. 2 hours ago, d'Hinnisdaël said:

    Shouldn't it be enough to associate the styles with the block page's id and make sure cloning a page also clones its associated styles?

    Thx for your input! Just to be sure we are on the same page here. 
    Iam talking about the parent page with my grid field, that holds all the childpages, lets call them blocks.
    So cloning this parent page from the page tree with the copy button, causes all the blocks on the clone to change their page id (need to be unique) and page name, the page title however will not change, so setting the title as the JSON ID will keep the styling information without any need for a comparison of IDs or additional fields. As I understand it, going with ids would need a hook on page add/clone to handle the switch of IDs or all the styling information is lost. Using the title field or a custom field to simply copy the same JSON id to the new page (page clone does this automatically) worked well so far.  Iam worried when external pages that already exists in the page tree are added to the page grid field (eg. via api) it would not be a good idea to use the title field here, because it maybe be accidentally changed by the user and lose its connection with the JSON id. Also not sure I was clear, the JSON data lives on the parent page, I only need a way to connect the blocks with the JSON id. Hope that makes sense ?

  8. Hey folks!
    Just wanted to give you an update on this. Iam close to an alpha release now. I added a lot of features (containers/groups, more styling options, api functions, optional webfonts/google fonts integration, UI improvments etc.) and bug fixes and now it feels quite stable. I still have to do some testing and some UI stuff. Iam really exited to show you the new version soon! ?

    Before I can post a final release date I have to think a little bit about how the JSON for the styling is saved and make sure that it's solid. I have two approaches and can't decide which one is best. Maybe someone, who used page table (my module uses templates/fields just like page table), can help me figure this out. It works like this:

    When a new block/page is added to the page table, my module auto generates a title and a name. The title is generated based on the name of the template the page item is using plus the page id.

    I title could look like this:
    block_image_5143

    This title (with sanitizer) is then used as an ID to save all the styling information for that item/page to my JSON field (it's also used to generate a css class name). The ID has to be unique in the context of the page containing the page table items. I figured I can't use the page id or the page name, because when a page containing a page table grid is cloned, all the items/pages added to the page table get duplicated and change their name and ids, so the clone loses all the styling information. So while it works great with the title field, it has the downside, that when the user changes the title, the connection to the ID/title in the JSON gets lost. So an alternative approach Iam considering now is to add an extra field to every page table item template automatically via api (pupulated on item/page creation), eg. pgrid_id. This field only has superuser access or is completly hidden. While this adds a little more overhead, it may be the better approach. What do you guys think is better?

  9. 19 hours ago, netcarver said:

    Highly recommend Gumroad for selling this. It takes care of all sales tax nightmares and can automatically generate a license key per sale.

    Gumroad looks very promising! Will take a closer look, that might just be what I need. From what I can see it's even possible to inform the customer of new versions of the module and adding subscriptions for support etc. Sweet! 

    • Like 2
  10. 21 minutes ago, rick said:

    Basically, the simplest solution, for example, is to use something similar to paypal's 'buy now' buttons; one for each license type. It really doesn't matter about a specific license ID unless you want to identify a particular user when they request support, etc., and then you can pass a unique ID which is returned with the transaction confirmation. In this example, you don't need to mess with any type of license key entry in your module; The customer just downloads the module from an email link. You insert the 'transaction id' in the email for their records that you can compare with your database entry at some future date.

    That seems simple enough, but that would not prevent the use of my module on multiple unregistered domains. Also not sure what you mean with "compare with your database entry at some future date"?  

  11. Hi folks,
    Iam working on a rather complex pagebuilder module, which took a lot of time to build.
    Now the module is almost ready and my plan is to release it as a commercial module at some point.
    This will help me to support the module in the future as well as cover some of the time/costs it took to make it.

    There will be 3 licenses:
    - Single website
    – 3 websites
    – 10 websites

    To protect the module from being used without a license, Iam looking for a simple way to generate a license key, that is tied to a domain.
    It don't has to be the most secure methode. If possible it will work without making a connection to an external server to check the key?
    I have no experience with this but I picture it may work like this:

    1. When the user buys the module, he/she needs to enter a domain, or multiple domains (based on the license).
    2. The user can download the module and gets a license key (generated based on the domains entered?)
    3. After installing the module in the backend, the user needs to enter the license key
    4. The module checks if the url matches the key and grant/denies acess.

    Another idea might be to use the userAuthSalt stored in the config file of PW to generate the key.
    But then the key needs to be generated after the module is installed.

    How would you generate the license key?
     

    • Like 1
  12. 1 hour ago, BitPoet said:

    Not necessarily in a noticeable way, but I'd expect that it would sooner or later bite you in the backside. If another redirect happens for any reason (https upgrade, change in subdomain, etc) beforehand, Google sees two consecutive redirects when accessing / and immediately penalizes you. Outside of web apps, I try to use redirects only for two reasons: either the site moved to a different domain, or the path to a page changed.

    Doing a redirect would be an easy solution. As I understand it, Google allows two redirects without a penalty. The only other redirect that could happen is the http to https or www to non-www. There are no subdomains planned, it's a very small website that is unlikely to grow much in the future. Do you think in this case the redirect would be ok?

  13. 14 hours ago, BitPoet said:

    That's the way I would do it. And make sure that you also set a canonical header in your home page that points to the Location-1 page so search engines know to treat them as one page instead of duplicated content.

    That will work, exept that the URL for the homepage would be casamani.com and not casamani.com/location-1. 
    Or is there any way around this? Not sure Iam thinking it through. 

  14. Hey folks,

    currently Iam working on a website for one of my clients and I need some advice on how to approach this in PW.
    The website is for a company, that offers holiday houses in two locations. 

    The client wants the homepage to show the first location. Normally I just have a home template for the first page, but here the URL should reflect that you are in Location 1. So when you visit the URL casamani.com it should redirect to casamani.com/location-1. Not sure if this makes sense at all.

    Whould it be bad for SEO and performance reasons to redirect home to the Location-1 page?
    Another approach would be to render the Location-1 template on the home template or do an include like discussed here.

    Here is how the tree looks:

    – Home

    – Location 1 (Homepage)
         – Creation
         – Adventure
         – Sustainability

    – Location 2 
         – Creation
         – Adventure
         – Sustainability


    Thanks for looking into this!

  15. One more question to finally understand php classes a little bit better:
    If I have this simple class:

    class PageGridCSS {
    
        public $cssClasses = 'test classes';
    
        public function getCssClasses() {
            return $this->cssClasses;
        }
    }

    How can I call the function getCssClasses from outside the file it is declared in?
    So far I was able  to call it from within the same file only by doing this:

    $PageGridCSS = new PageGridCSS();
    $PageGridCSS->getCssClasses();

     

  16. @MoritzLost Thanks again! This seems to be the best way to handle it. I will further investigate if it complicates my current setup too much. But I get the benefits now. Hopefully this will help others too. 

    I'm generally ok with making some assumptions in my case, because you can change the CSS stuff inside the backend for each item (and the breakpoints you want) anyway, also its easy enough to overwrite some css rules with plane css/scss. Maybe I provide some api options and helper functions along the way, so this is definitely helpful. Here is a preview of the module I'm developing to give you a little more context:

     

    • Like 1
  17. I'm still a little lost on how to implement my JSON decode method and use WireArray as a representation of my data.
    My module builds a dynamic stylesheet, based on the JSON file. This dynamic stylesheet is just a php file that the user can include in his/her main template file. The JSON is saved in one field, that live on the page holding all the PageTable items.

    Since I need the CSS to be rendered  in the backend and frontend and I wanted to give the user more freedom on where to include the CSS I thought this is a good approach. Not sure if it's really clever to have this in a separate file instead of my module file. 

    This is my working code I have in the dynamic stylesheet file:

    <style>
    <?php 
    namespace ProcessWire; 
    $backend = 0; 
    $p = $this->page;
    
    if($isAdmin = $this->page->rootParent->id == 2) {
    $p = $this->pages->get((int) wire('input')->get('id'));
    $backend = 1; 
    }
    
    $css='';
    $settingsArrayPage=json_decode($p->pgrid_settings);
    
      if( !(empty($settingsArrayPage))) {
    
           foreach($settingsArrayPage->items as $item) { 
               
               foreach($item->breakpoints as $breakpoint) { 
                 
                 if ($backend) {
                   $css.='.breakpoint-'. $breakpoint->name . ' ';
                 } else {
                   $css .= $breakpoint->size . '{ ';
                 }
                
                $css .= '.' . $item->cssClass. '{ ';
              foreach($breakpoint->css as $style=> $val) {
                       $css .= $style . ': ' . $val . '; ';
                   }
                 
               $css .= ' } ';
                 if (!$backend) {
               $css .= ' } ';
                 }
             }
                
           }
      
      echo $css;
        }
     ?>
    
    </style>

    First of all where would you put the WireArray code? Is it better to have this in my module file or in the dynamic stylesheet file?
    Here is my code so far.

     class PageGridData extends WireArray {
        
       public function getItemKey($item) {
    // here I would place the JSON decode method from above and return the items?
    		return $item->id;
    	}
        
        }

    Sorry this is a bit outside of my comfortzone ?

  18. @MoritzLost Thank you for the detailed answer! I'm still at a very beginner level with php, all I know about it, I basically learned from using PW and it's api. Doing mainly frontend development, this is the first bigger module I'm building. So I'm still new to how classes work. Now that I have another look at it, what you sad makes a lot of sense. I will try to implement the class approach with my own utility methods.

    I will also have a look at WireArray, this seems like a nice solution.
    Thanks again for your help. I might come back at you if I hit another roadblock.

    • Like 1
  19. @bernhard Thanks for your examples. It does look simple to create a migration. It would be nice if a non technical person could then easily paste that code into the backend, click a button and everything is imported. Is that possible with your module? I don't want that person to open an editor, that person might not even have access to FTP. With  adrians migrator module it's possible to import the code/JSON in the backend and create all the pages, templates and fields in one import. I'm not saying that this is somehow better than how your module works, it just might be better suited for my usecase. Your module clearly has a lot of benefits compared to migrator.

  20. 21 minutes ago, bernhard said:

    Have you had a look at RockMigrations? You get the best of both your worlds: Easy migrations + version control...

    I saw this a while ago, but just had a brief look at it. I will play around with this some more, but this might be even too complicated for my needs. The target group for my module are not only web developers, but also non technical people like designers, experienced editors, or marketers. I need a way for these people to import new blocks as well. 

  21. here is another possible structure

    {
      "items": [{
        "id": "3252",
        "cssClass": "pgrid-main",
        "breakpoints": {
          "base": {
            "css": {
              "grid-column-end": "auto",
              "grid-row-end": "auto",
              "grid-column-start": "auto",
              "grid-row-start": "auto",
              "align-self": "auto",
              "z-index": "auto",
              "padding-left": "60px",
              "padding-right": "60px",
              "padding-top": "60px",
              "padding-bottom": "60px",
              "background-color": "rgb(255, 255, 255)",
              "color": "rgb(0, 0, 0)"
            },
            "size": "@media (min-width: 576px)",
            "name": "base"
          }
        }
      }, {
        "id": "3686",
        "cssClass": "test_global",
        "breakpoints": {
          "base": {
            "css": {
              "grid-column-end": "-1",
              "grid-row-end": "span 1",
              "grid-column-start": "1",
              "grid-row-start": "auto",
              "align-self": "auto",
              "z-index": "auto",
              "padding-left": "0px",
              "padding-right": "0px",
              "padding-top": "0px",
              "padding-bottom": "0px",
              "background-color": "rgba(0, 0, 0, 0)",
              "color": "rgb(0, 0, 0)"
            },
            "size": "@media (min-width: 576px)",
            "name": "base"
          }
        }
      }, {
        "id": "3687",
        "cssClass": "block_editor-3687",
        "breakpoints": {
          "base": {
            "css": {
              "grid-column-end": "span 5",
              "grid-row-end": "span 2",
              "grid-column-start": "2",
              "grid-row-start": "2",
              "align-self": "auto",
              "z-index": "98",
              "padding-left": "0px",
              "padding-right": "0px",
              "padding-top": "0px",
              "padding-bottom": "0px",
              "background-color": "rgb(255, 204, 204)",
              "color": "rgb(0, 0, 0)"
            },
            "size": "@media (min-width: 576px)",
            "name": "base"
          }
        }
      }, {
        "id": "3696",
        "cssClass": "block_editor-3696",
        "breakpoints": {
          "base": {
            "css": {
              "grid-column-end": "span 2",
              "grid-row-end": "span 1",
              "grid-column-start": "auto",
              "grid-row-start": "auto",
              "align-self": "auto",
              "z-index": "auto",
              "padding-left": "0px",
              "padding-right": "0px",
              "padding-top": "0px",
              "padding-bottom": "0px",
              "background-color": "rgba(0, 0, 0, 0)",
              "color": "rgb(0, 0, 0)"
            },
            "size": "@media (min-width: 576px)",
            "name": "base"
          }
        }
      }],
      "breakpointActive": "base",
      "breakpointActiveSize": "@media (min-width: 576px)"
    }


     

  22. @MoritzLost Thanks for your explanation! Helps me to understand this a little bit better.

    2 hours ago, MoritzLost said:

    Of course you can just json_decode the JSON string and pass the result to the user of your module. But that's a bad idea:

    Iam not sure the data will ever be relevant to the user, for now I just use the JSON internally (creating JSON with js and decoding it with PHP). What I meant with "using objects instead of arrays" here is just how I decode the JSON in php: json_decode($jsonString) instead of (json_decode($jsonString, true). This gives me easy access to the items (which are just pages, so I thought it would be nice to be able to access them by page id like the pw api works). To be able to do this I also need to create the JSON structure like in the example above (with JS). Hope that makes sense. Not sure if the cons you listed matter that much in this case. I will think about it.

    2 hours ago, MoritzLost said:

    If you want to build closer to ProcessWire, you can also use a class that extends WireArray to represent a list of items, this will give you many helpful methods (like getting an item by key) out of the box. For the items themselves, you might just reuse the page itself (if the IDs correspond to 'real' pages in your system) or extend the Page class.

    This sounds interesting. Maybe you can provide an example how to extend WireArray?

     

×
×
  • Create New...