Jump to content

a-ok

Members
  • Posts

    812
  • Joined

  • Last visited

Posts posted by a-ok

  1. I'm attempting to change the page name of a page, when it is saved, using the API. Below is my hook. The message appears (as a test) but the change never happens. Any thoughts?

     function myHook(HookEvent $event) {
     	$page = $event->arguments(0);
     	if ($page->template->name == 'work-detail') {
    		if ($page->global_text) {
    			$pageName =  wire()->sanitizer->pageName($page->title . '-' . $page->global_text, true);
    		} else {
    			$pageName =  wire()->sanitizer->pageName($page->title, true);
    		}
    		wire()->message($pageName);
    		$page->setOutputFormatting(false);
    		$page->setAndSave('name', $pageName);
     	}
     }
     wire()->addHookAfter('Pages::save', null, 'myHook'); // On page SAVE run this hook

     

  2. Why does this return null?

    $page->products_sku->type

    I thought you could check a field's type? I know this works...

    $fields->products_sku->type

    But if I have the following, how could I check the type?

    $slides = $page->products_sku;
    // I need to return $slides type
    bd($fields->products_sku->type);

     

  3. 19 hours ago, Robin S said:

    You must have an old version of FieldtypeTable - it has included Page column types since 2015: https://processwire.com/blog/posts/major-updates-to-profields-table-field/#new-support-for-single-and-multi-page-reference-fields

    Perfect. Thanks so much. I like the idea of using ProTable for this rather than a Repeater to reduce overheads.

    Much appreciated everyone.

    • Like 1
  4. 9 hours ago, Robin S said:

    If I understand right you need to use a repeating fieldtype that contains a Page Reference field and a text field for the unique code. You could use any repeating type such as Repeater, PageTable or ProFields Table, but I think ProFields Table would be the optimal interface. You can use some custom JS in Page Edit to disable options in the Page Reference field that have already been selected in another row of the table - just shout if you need advice for doing that.

    Okay great so that's the best way to do it. ProFields Table! I prefer this to the Repeater field too. I really appreciate everyone's help.

    I think I'll add the JS to a hook under ready.php (stupidly I didn't know you could add JS to this?)

  5. 1 hour ago, wbmnfktr said:

    WHO defines the total code. Does your client say "Product D with Source  Z,D, and H has total code [WH-ATS-OEVER]"?

    Correct but the total code is only based on the product with one source. Product D with source Z = 123, Product D with source D = 456, Product D with source H = 789. There is a single code per product+source. The client states this. It needs an entry for each 'source' they choose per product.

    I reckon your method makes sense but just seems time consuming for the client but maybe that's how it is. Why they couldn't just have a code for each source and code for each product and the total code is them concat'd together. But alas.

    1 hour ago, wbmnfktr said:

    And another thing... what if a product has only one light source and not ten or seven or four? Can they even be mixed in that way or is there another dependency?

    It shouldn't matter based on my explanation above.

  6. 1 hour ago, wbmnfktr said:

    That's possible and needed actually.

    • Products
      • product #1
      • product #2
      • product #n
    • Sources
      • source #1
      • source #2
      • source #2
    • Total codes
      • total code #1
        • product #2 ref
        • source #1 ref
      • total code #2 
        • product #2 ref
        • source #2 ref
      • total #n
        • product #1 ref
        • source #n ref

    This isn't a bad idea and is how it is almost set up just now but just seems like A LOT of data input for very little return? Having to add each total code separately, outside of the product context, then reference a product and source (assuming by two PageFields on the total code page?) – it might be the only solution, however! ?

  7. 1 hour ago, dragan said:

    Is the ultimate goal to create URLs that automagically "assemble" the product with all parts? Did you consider using URL-segments? You could use something like
     mysite.tld/products/product-page-slug/lights/5001/5002/5003/

    No, sorry. I have clearly confused everyone.

    Each product has a 'light source' PageField which chooses the 'light sources' for each product. One product may have 10 light sources, another maybe one.

    158099696_ScreenShot2019-06-14at18_53_28.png.af21d13bb8e775b4371c6fc12a491f85.png1675228454_ScreenShot2019-06-14at18_53_37.thumb.png.e589b77be6d770c66b8432c038f5426e.png

    The issue is that I need to add a 'unique product code' (almost like a SKU) that only exists for a product and light source combination. So if I was editing product A and chose LED35 GEN2 from the light source I would need to enter a unique code for that combination of product and light source. Same if I then choose another light source. Then when editing another product (product B) and adding a light source to that, it would, again, be unique/different.

    I need a way, when choosing a light source for a product, to enter a unique code for that selection, for each selection. This needs to be inputted manually.

    Hope that's cleared things up?

  8. It's interesting and really appreciate your reply. The only issue is I try to keep things as three dimensions as possible so no rabbit holes. Product and source are all their own tree so everything is on the same level.

    I use @Robin S's PageFieldConnector module which seems to work well but I can't see it being useful in this instance. The total code is only relevant to the product and source code chosen (by PageField at product level) in that context/instance.

  9. I'm building a website that houses all different kinds of 'lights'. Lights (let's call them 'products') are all pages and a 'product' can have any number of 'light sources'. Each 'light source' is a page and within a 'product' you can use the PageField field to select as many options as you want. Easy.

    Each 'product' and 'light source' combination has a unique 'code' but I'm struggling to work out where to add this. It would be ideal if each product has a code and each light source has a code then the total code is them both together... but it's not. A total code is random – there's no 'formula' – so I'm wondering how best to implement this? Ideally it would be some sort of 'Within your product you choose your light source and supply the code at the time of choosing' – but that's not possible.

    Do you think, on save, using a hook, it could populate a repeater field or table with the 'light source' pages chosen and each 'row' has a separate field for the code? I need to output this on the front end too but I could cross reference the PageField (light sources) with the hooked repeater and return the total code that way?

    Does anyone know if I'm missing something obviously simple to allow this sort of functionality or is my suggestion the best route?

    Thanks!

  10. 8 hours ago, Robin S said:

    The status flags are bitwise so if you use a flag value directly to find published pages it would need to be like this:

    
    projects_awards.owner.status<2048

    But for PageFinder selectors you can use a string for status:

    
    projects_awards.owner.status!=unpublished

    You would also want to exclude unpublished repeater pages because otherwise you can get unfilled "ready" repeater pages in your result. So your selector would be:

    
    template=repeater_projects_awards, projects_awards.owner.status!=unpublished, status!=unpublished, include=all

      

    This is amazing. PW is so so so good. Much appreciated, @Robin S and the others ?

    • Like 1
  11. I'm trying to be smart and use the `owner` selector.

    I'm using a repeater `projects_awards` on a `projects` template that has about 20-30 pages and want to retrieve all the repeater rows on a separate page `About`.
    I could either query all the projects, that have `projects_awards.count>0` then loop through those but that doesn't seem very efficient. I could just query the repeater template `template=repeater_projects_awards` but then that would return the rows even if the page it is on (owner) is unpublished. You see my dilemma.

    I thought this could work...

    template=repeater_projects_awards, projects_awards.owner.status!=2049, include=all

    But returns empty – am I using this correctly?

  12. 1 hour ago, szabesz said:

    Not really. It depends on how you find something easier to implement. Usually I use include but I try to avoid relative paths. There is a "problem" with them: http://yagudaev.com/posts/resolving-php-relative-path-problem/ 

    BTW dirname('__FILE__') is the same as __DIR__

    I only use wireRenderFile() when I want to store the rendered output in a variable, and I use this technique to avoid the hassle of passing lots of variables: https://processwire.com/talk/topic/14332-storing-templates-in-separate-directories/?do=findComment&amp;comment=129024

     

    Thanks, this is really great and helped me loads.

    Is there a reason you use $config->paths over $config->urls?

    • Like 1
  13. I apologise in advance if this is more a 'PHP' issue than a 'PW' issue.

    I have an include in one of my templates:

    foreach ($query as $item) {
        include('./inc/item__project--filter.inc');
    }

    And within this include I have another include (as I tend to build in re-usable modules):

    include("./slider__v--horz.inc");

    Both includes are within the `/inc/` folder within templates.

    If I visit this page then it all renders fine, but when I use an AJAX request to render the first include (when the selector for the page changes), it returns an error:

    PHP Warning: include(./inc/slider__v--horz.inc): failed to open stream: No such file or directory in .../www/lucent-lighting/inc/item__project--filter.inc:10

    On the template that both these includes are being used (projects.php) I am executing the following check with the AJAX request (GET) is fired

    if ($this->input->get->action == 'filterEndpoint') {
    
    	$inputExists = $this->input->get->inputExists;
    	$filterEndpoint = $this->input->get->filterEndpoint;
    
    	if ($this->input->get->pageTemplate == 'projects') {
    
    		if ($inputExists !== "") { //
    			$query = $pages->find("template=products-filters-single, products_filters_projects.count>0, include=all, sort=sort, {$filterEndpoint}");
    		} else {
    			$query = $pages->find("template=projects-filters-single, projects_filters_projects.count>0, include=all, sort=sort, {$filterEndpoint}");
    		}
    		$itemTemplate = './inc/item__project--filter.inc';
    		//bd($query);
    	}
    
    	$output = '';
    	foreach ($query as $item) {
    		$output .= wireRenderFile($itemTemplate, array('item' => $item, 'inputExists' => $inputExists));
    	}
    
    	return json_encode(['html' => $output]);
    
    }

    Any thoughts?

  14. 13 hours ago, Robin S said:

    Works for me too, but would depend on what $config->urls->root is (e.g. if developing in a subfolder?)

    If it's just MSN you are concerned about the simplest thing is to use the features built into MSN for just this purpose. Either then "xitem_tpl" option or a "getItemString" hook:

    
    // MSN hook for external_link template
    $nav->addHookAfter('getItemString', function($event) {
    	$child = $event->arguments('page');
    	if($child->template == 'external_link') {
    		$event->return = "<a href='{$child->link_url}' target='_blank'>$child->title</a>";
    	}
    });

     

    Thanks. I can't get it to work but my $config->urls->root is "/jamb/" as I am working locally (and my dev server has a similar setup) of sub-folders (root > each project). Would be good if we could amend this regardless (maybe on the roadmap?) but thanks (and @adrian too) for the explanation.

    Re the hook onto 'getItemString' – I'm actually using this to concat an item... for some reason I didn't think to use it to alter the item itself. So that works.

  15. 21 minutes ago, adrian said:

    The issue is that hooking the path affects the relative url, not the full http url. You can do a redirect to that $page->products_categories_external rather than an $event->return.

    You could do this from your path hook or maybe it might even be better to do it from Page::render

    Do you mean a `$session->redirect()`? Hmmm...

  16. 6 minutes ago, adrian said:

    Changing the path will result in a changed url so I guess I am missing the point somehow.

    Here is the classic thread on this topic: https://processwire.com/talk/topic/1799-routes-and-rewriting-urls/

    I thought so too but all I get is

    `https://local.dev/jambhttps://www.hawkerantiques.com`

    Maybe it's related to `MarkupSimpleNavigation`

    EDIT: It's not... it happens with normal `$page->url` outputs.

  17. 20 minutes ago, elabx said:

    What I've done in this scenarios is adding a new method through a hook to pages,  something like $page->customUrl() that checks conditions before outputting the url. 

    You mean something like this?

    wire()->addHookMethod('Page::customUrl', function($event) {
    	$page = $event->object;
    	if ($page->products_categories_external) {
    		$page->url = $page->products_categories_external
    	} else {
    		$page->url = $page->url;
    	}
    });

    The issue is I'm using `MarkupSimpleNavigation` (so normally I'd just write a check) which is why I was thinking a hook that would modify the URL.

  18. I'm aware you can change the path of a path by hooking into `Page::path` but I need to amend the URL rather than the path (change it to an external URL that's in a field on the page).

    $pages->addHookAfter('Page::path', function($event) {
    	$page = $event->object;
    	if ($page->products_categories_external) {
    		bd($page);
    		$event->return = "$page->products_categories_external";
    	}
    });

     Any thoughts?

×
×
  • Create New...