Jump to content

mindplay.dk

Members
  • Posts

    305
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by mindplay.dk

  1. FYI, the member list suffers from the same thing but much worse - shows 3 page links for 46 total pages...

    EDIT: the "sort order" links on the member list also don't work - they don't toggle between ascending/descending when you click them.

    Wow, this forum software really is full of bugs...

  2. PS: things are already simple - nothing wrong with making them simpler though, especially when it's no additional work or overhead for those using the module and working with an IDE.

    For me, personally, having full IDE support for any piece of PHP software has become a sign of high quality - it means everything can be validated automatically, which usually means it has been. You can't expect a person to do the same for 10,000 lines of code on every release. And vice versa, if a computer can't infer the meaning of your code, how can you expect a person to?

    Whether you have IDE support for the users who use an IDE or not, having IDE support means you have automatic safeguards and checks that cannot be performed by a person.

    • Like 4
  3. You only have a handful of Page objects and Fields? I think you misunderstood - this does not provide IDE support for ProcessWire (which still needs a lot of work in this area) but for your templates and fields. I'm sure you have more than a handful on complex sites, and I'm prertty sure they're not always the same? :)

    It's not about simple or difficult, it's about proofing your work - knowing in advance if you misspelled a property-name, or not having to go back to find the name of a property on an admin-screen, it saves time. With inspections in PhpStorm, there is also the added benefit of being able to automatically find errors - if you have dozens of templates and you have to make a change like renaming or deleting a field, automatic inspections will instantly reveal which templates are affected.

    Most of my day-to-day work is not little projects, but large complicated business-systems - while I used to be able to keep it all in my head, I'm not getting any younger. A good IDE will help you stay fast and accurate when you grow older, wait and see ;)

    • Like 4
  4. Some updates: a use-clause is now generated, pretty big oversight there. PageReference types are now documented with their pseudo-types, which means you'll be able to directly follow a reference to a related page (or list of child-pages) while still getting IDE support.

    I simplified the class-name convention - "basic-page" now simply becomes "tpl\basic_page".

    And the generated documentation can now be viewed on the configuration-screen - you will see it when you install the module.
  5. In Fields.php#415, the invokation of changedType() doesn't match the hook method - you forgot to pass in the $fromType and $toType arguments.

    EDIT: I added the missing $fromType and $toType arguments and integrate the new hooks - I noticed one important change immediately, when changing the Field-type, there are actually two events during the same request, first changedType() and secondly saved(), and those get correctly recorded as one migration, in the correct order. So this works much better and is surely much safer than the controller-hooks. Thanks!

    • Like 1
  6. I just noticed something odd too - sometimes, the number of pages is incorrect when you're viewing page 1 of a longer discussion.

    See here for example - it displays "page 1 of 4", but it only shows page links for pages 1 through 3 ... once you go to page 2 or higher, the 4th page link appears.

  7. This module generates a "stubs.php" file containing PHP-classes with documentation for the properties of each Template, based on it's fields - which means IDE support (auto-complete, inspections, documentation) for templates in modern IDEs that perform static analysis, such as PhpStorm.

    The output looks like this:

    <?php
    
    /**
     * Generated by TemplateStubs module 2013-04-13 15:29:33
     * This file may be overwritten at any time.
     */
    
    namespace tpl;
    
    use Page;
    
    /**
     * "basic-page" template
     *
     * @property string $title Title
     * @property string $headline Use this instead of the Title if a longer headline is needed than what you want to appear in navigation.
     * @property string $summary Summary
     * @property string $body Body Content
     * @property string $sidebar Sidebar
     * @property Pageimages|Pageimage[] $images Images
     */
    class basicpage extends Page
    {}
    
    

    To use the generated documentation, start your template-file like this:

    <?php
    
    /**
     * @var tpl\basicpage $page
     */
    
    

    Documentation and more details on this page:

     

    You can consider this an alpha-release - I haven't tagged a release yet, and some details like template-class naming convention may change before I tag release 1.0.

    • Like 9
  8. Sounds good - though I am somewhat concerned about the reserved keys in $options, but I guess that's inevitable since they're already in use. They should probably be documented in the API, so that people don't accidentally overwrite reserved values. EDIT: you did already document them :)

    • Like 1
  9. @nik Gotcha! Thanks, that works better :-)

    @ryan I favor the first option - I would prefer to have execute() and finished() trigger consistently. However, it may break backwards compatibility with existing modules that rely on finished() not getting triggered. Probably very marginal, though in theory it could cause a hiccup in some module...

    ProcessWire::shutdown() would be my second choice - if that's what you choose to do, I think it would also make sense to pass an argument to the hook, indicating what the result of the request is, e.g. the HTTP status code, or maybe just a true/false flag indicating whether the result is a redirect?

  10. Yeah, I tried a before-hook on Session::redirect() but that doesn't seem to work either...

    I've resorted to __destruct() before but don't feel comfortable doing that in this case, since the order in which other objects get destroyed is unpredictable and might cause weird side-effects - if wire('templates') or one of the Template objects have been destroyed by the time my __destruct() method is called, for example, iterating through Templates or saving them could go horribly wrong.

    I posted the code here...

  11. Is there a reliable shut-down or post-request hook in ProcessWire?

    I tried ProcessPageView::___finished() but it doesn't get triggered when there's a redirect - most admin-forms use a post/redirect/get approach, so there's no hook until the following request, which is too late.

    What I'm trying to do, is raise a flag on a number of different events - if templates or fields are saved, for example, I need to do some work when the request ends. Since the Session::redirect() method does a hard exit() the invokation of finished() in "index.php" is missed...

    Any ideas?

  12. Looks like FieldtypeDatetime currently ignores timezone issues?

    Seems like this needs to be addressed somehow, at some point - it's fine if your applications are used in one timezone exclusively, or if users are aware that all timestamps are in ET say, but it seems this is going to be inadequate for applications used even across multiple timezones in the US, which most US applications probably are.

    This problem is particularly serious if you're storing dates only - since, without timezone information, a single date actually spans a 48-hour period worldwide. You can't really convert dates if you don't have a time.

    I would strongly prefer to have all timestamps stored in UTC in the database - with the ability to auto-detect a default timezone for anonymous users, and selecting a timezone for registered users. Anything like that already in the pipeline?

    • Like 3
  13. there's a lot more thinking behind the design than you often assume.  

    Just re-read your message, and just wanted to make this clear: I do not make assumptions about your design.

    When I ask questions, challenge your ideas, or propose alternatives, I'm merely testing the boat to see if it holds water - it's nothing personal, it's just the way my mind works. And most of the time, you are able to clarify your objectives or explain your choices to my satisfaction :) ... as Einstein said, "question everything" - this is how we arrive, not at perfection, but as you say, the best possible choices gives the context and goals.

    Please assume that I'm trying to help - if my tone suggests otherwise, I apologize, I'm not always eloquent with my words.

    I never got on the Drupal, Joomla or WordPress forums to try to help there - because I never saw any of those projects as being worth my time. This project is. So I hope you'll put up with me, even if I ask obnoxious or provocative questions at times.

    As Rafael Dohms just pointed out on Twitter: Discussion is evolution, whether you are right or wrong the exercise of discussing will teach you something new.

    :)

    • Like 6
  14. Templates need to be aware of context either way - this way, you can actually do a simple check to see if a context was provided at all: isset($data) - plus it makes it easier to pass the entire context on to another child-template.

  15. Possibly what makes the most sense, is to just pass one variable? The developer can pass an array or a single string, or an object, e.g. for strongly typed view-models if wanted. If you did want to pass an array and have it extracted as local variables, all you'd have to do is call extract($data) in your child-template - it's not a lot of work...

    • Like 2
  16. My problem is this:

    class Collection
    {
        public function save()
        {
            if (conditions) {
                onBefore()
                doStuff()
                onAfter()
            }
        }
    }
    

    Because the event system already uses the before and after concepts, it gets confusing - the above could be simplified as:

    class Collection
    {
        public function save()
        {
            if (conditions) {
                $this->doStuff()
            }
        }
    }
    

    Because I can already hook doStuff() both "before" and "after", you just need an inner and an outer method. "ready" is just a synonym for "before". You said yourself, it doesn't matter if you hook those "before" or "after", because nothing actually happens inside them...

  17. Looks like added() and saved() are both being called on save() ?

    It's a bit confusing with the high number of events - I can't imagine I'll need all those? I'm really not a fan of the word "ready", it's meaning is never really clear - ready for what? ... is it a good idea to have so many of these "vestigial" methods?

    I think I'll just take a stab at this working from the current code in Git - and then see if I need any new events, how does that sound? I'd rather not bear the guilt of making you muck up your elegant tidy codebase with all this junk just for my sake :)

  18. Okay, I did some work on this today - adding, updating, renaming, deleting and changing the type of Fields now records and repeats.

    I have only done some superficial testing of this: created and deleted some fields, changed properties on various tabs, renamed a Field, deleted one, and was able to repeat all of those actions, without problems. Tables were correctly created, renamed and deleted during those operations.

    I'm impressed with how robust ProcessWire is in this regard - because the important stuff really does happen at the API-level (rather than in controller/action methods) all the operations are easily repeatable and the results appear to be consistent :)

    Nice work @ryan !

    Now, there is one thing that concerns me.

            $this->addHookAfter('Fields::load', $this, 'hookFieldLoaded');
            $this->addHookAfter('ProcessField::fieldSaved', $this, 'hookFieldSaved');
            $this->addHookAfter('ProcessField::fieldAdded', $this, 'hookFieldAdded');
            $this->addHookAfter('ProcessField::fieldDeleted', $this, 'hookFieldDeleted');
            $this->addHookAfter('ProcessField::fieldChangedType', $this, 'hookFieldChangedType');
    
    

    I'm hooking into Fields::load to obtain a copy of all the Field properties before any changes can be made to these.

    But in order to capture the changes, I had to hook into the ProcessField::field* methods, which appear to be there for the purpose of monitoring these events.

    My concern is that those events only fire when changes are made via the ProcessField controller - and that this is not (necessarily) the only way to make changes to Fields. (I no longer recall why I had to use the controller-level events, as opposed to hooking into the Fields collection-level events - I will investigate this further the next time I work on this.)

    I would really like to hear from @ryan on this one before I continue - there are currently no equivalent controller-level events for Templates (e.g. in ProcessTemplate) as far as I can tell? So currently the only option is to hook directly into the Templates collection methods.

    • Like 4
  19. I have been asked numerous times in the past to upgrade various projects from GPL2 to 3, and have willingly done so.

    My policy has always been quite simple - there is only one scenario where I could picture enforcing my legal rights: if somebody were selling my product (or a derivative product) and passing it off as their own. I feel comfortable that both GPL2, GPL3 and MIT protects me in that situation.

    Other than that, I don't really care what people do with my software. Simple :)

    I think, at the end of the day, precisely what license is used probably matters more to the consumer than to the vendor - and for various reasons, consumers seem to prefer GPL3 or MIT.

  20. It's how most view-engines work, I suppose - the render() method usually takes the name of the view and the data to render.

    I'm not sure precisely how we would get around the fact that numerous variables are already in scope by default, however?

    If you pass array('page'=>'foo') will the "real" $page get overwritten? do you lose that variable? or do you get an Exception? 

    Perhaps better would be to pass additional view data as a single variable rather than extracting it before rendering? e.g. $view or $data or someting?

  21. Do you think it would make sense for the render() method to also accept a second argument: an array of values to pass to the template of the sub Page?

    As explained, I'm really not keen on adding transient values to Page objects - which would be (and currently is) the only other way to pass options to sub-templates...

    • Like 1
  22. To clarify, by "parent template", I simply mean the template of the Page object that was dispatched - and by "child template", I mean the templates of any other Page objects related to the parent.

    What I'm currently doing, is either rendering child content directly from within the parent template, or using include/require to pull in an include file used to render a child template.

    What I'd like to be doing, is simply loop over child Page objects and call render() - as explained, that rarely works, because child Page objects usually are a full page; they're not designed to render inline - with the exception of things that are strictly child Pages, never themselves rendered as a parent, i.e. never dispatched directly.

×
×
  • Create New...