Jump to content

OMG!.. help with URL SEGMENTS please!


Pixrael
 Share

Recommended Posts

I have a parent page (with template file) with several child pages (without template file) that are hidden and unpublished, I use them only to store information. The parent page have the url segments enabled.

When I catch the segment in the template file, works as expected for any word, but if the url segment match the property "name" of any child page, PW launch a 404 Page Not Found.. I try all combination of "hidden" and "Publish" for the child pages.

The idea is to render the data from the parent page plus the data of a child page, and get this data using an url segment (links generated dynamically) with the same name that this hidden page have.. I don't like having a template file for these child pages that only execute the render of the parent page with the information .. I want the previous solution if it possible

I was able to explain well? ...What happen here?

Link to comment
Share on other sites

I found why :-(

https://processwire.com/docs/tutorials/how-to-use-url-segments/page2

"You can use URL segments on any page where your template settings allow, regardless of whether it has children or not. Should there be a child page that has the same name as a URL segment that the parent page's template is looking for, the pages in the tree always have precedence. Meaning, URL segments only apply if the requested URL did not resolve to an actual page. As a result, you should avoid using URL segments where you think the page names and URL segments could collide"

Link to comment
Share on other sites

maybe you can use the page id as url segment? then you do not have the name conflict (or at least you would only have it if a page with the name of another page's id exists, what should be at least very unlikely or if you take care of this would be impossible).

ps: or you take an url segment like #getcontent#123 and then you strip off the #getcontent# part and request the page's content by the id

Link to comment
Share on other sites

abdus: I think your solution don't resolve my problem, I'm still have the match between both urls (segment and existing page), this option only allow me to auto generate the children names, this is not my case.

bernhard: this is a correct solution, in the first instance I not use it because the SEO.. maybe I need to use it.. :-(

Another solution should be put the "child pages" under another parent (empty template) only for hold it and to avoid conflicts

Thanks guys for your time!

Link to comment
Share on other sites

1 minute ago, Pixrael said:

bernhard: this is a correct solution, in the first instance I not use it because the SEO.. maybe I need to use it.. :-(

then i didn't understand your question, because my solution would have nothing to do with seo ;)

Link to comment
Share on other sites

i know that this would change

1 hour ago, Pixrael said:

The idea is to render the data from the parent page plus the data of a child page, and get this data using an url segment (links generated dynamically) with the same name that this hidden page have.. I don't like having a template file for these child pages that only execute the render of the parent page with the information .. I want the previous solution if it possible

but i thought you maybe request only some content via ajax or the like and populate areas in your parent page's template. i don't really get what you are trying to achieve and what the problem would be with a template for your child pages... :) but it's late here ;)

Link to comment
Share on other sites

If pages are not public, then you wouldnt need to worry about SEO.

Page name format works for pages created in the future, but for the current pages you can do:

$codes = wire()->pages('template=code');

foreach ($codes as $c) {
    // wall-mount-mini-split becomes code--wall-mount-mini-split
    $replacement = "code--{$c->name}";
    $c->of(false);
    $c->setName($replacement);
    $c->save();
}

And in your template, where you check urlSegments:

if($input->urlSegment1) {
    if ($input->urlSegment2) throw new Wire404Exception();

    $codeName = "code--{$input->urlSegment1}";
    $codeName = $sanitizer->pageName($codeName);

    $code = $pages("template=code, name=$codeName");
    if(!$code->id) throw new Wire404Exception();

    // do sth with the code page
}

 

  • Like 2
Link to comment
Share on other sites

... Ooooh. I forgot it.. I'm in Florida (Waiting for the big hurricane uff) ...

but is ok, maybe I don't have other solution than the IDs.. and I don't want to my editors to put the information in another place on the page tree when they should be under codes node...

So, the last shoot.. the scenario is:

Codes (template file)
-- Wall Mount (template without file)
-- Light Commercial (same as above)

Initially Codes render its content (header, body, etc) plus the information of the first child (repeaters with body, pictures, etc)

Codes also have a list of links that was generated from its children name as url segments, to load the same Codes page, but with the content from the new selected child

.. uff seems more easier to see than to explain !

 

EDIT: this post should be before the previous from abdus, I delay in publishing it

Link to comment
Share on other sites

abdus code would work great, but still i don't understand what is bad about having a template file for each of your children. url segments in those cases have some drawbacks that you may not think of before and always need some extra work (for example creating a sitemap, multilanguage or the like...).

hearing that this scenario makes problems for you i guess maybe your setup is not optimal. using https://processwire.com/docs/tutorials/how-to-structure-your-template-files/page4 this would be very easy.

and using https://processwire.com/blog/posts/processwire-3.0.62-and-more-on-markup-regions/ it would be even easier.

Link to comment
Share on other sites

Abdus: the problem is that in the parent page I generate the links automatic from the name of the child pages, so the links always match the children names.. even if I add "code--" using the API because when I save the page, and later generate the parent page again the links will include "code--".. the only solution is to use a field other than the name ... ID is the best option because is url friendly..

Abdus: Thanks for your contributions to this forum, you are the best teacher for newbies like me, every post of yours seems a tutorial. It's easier to learn new things in them than with the PW documentation.

Link to comment
Share on other sites

URLs are generated from page names by default. What I'm trying to show is that you dont have to use IDs for page names, otherwise when generating URLs you'd get /codes/123 instead of /codes/wall-mounted-light. Below is a sample template that should work in your case

<?php namespace ProcessWire;
/** @var Pages $pages */
/** @var Sanitizer $sanitizer */

/** @var Page $child */
$child = null;
if ($input->urlSegment1) {
    $codeChildName = "code--{$input->urlSegment1}";
    $codeChildName = $sanitizer->pageName($codeChildName);

    $child = $pages("parent=$page, name=$codeChildName");
    if (!$child->id) throw new Wire404Exception();
}
?>
<div class="code-page">
    <?php if ($child): ?>
        <!-- RENDER CHILD PAGE -->
        <h1>Child: <?= $child->title ?></h1>
        <?= $child->body ?>
        
    <?php else: ?>
        <!-- RENDER CODE PAGE WITH CHILDREN -->
        <h1><?= $page->title ?></h1>
        <?= $page->body ?>

        <h2>List of children:</h2>
        <ul class="chilren">
        <?php foreach ($page->children as $c): ?>
            <?php $childUrl = "./$c->name"; // generate urls for the child ?>
            <li class="child">
                <a href="<?= $childUrl ?>"><?= $c->title ?></a>
            </li>
        <?php endforeach; ?>
        </ul>
    <?php endif; ?>
</div>

I also concur with @bernhard. If you're modifying the core behavior and rendering child page at the url that matches the child's, then I'd say you should reconsider your approach. You're only complicating it for yourself.

Also, thanks, I'm doing what I can. These questions are like quizzes that I enjoy solving, and get to practice coding with PW.

  • Like 4
Link to comment
Share on other sites

abdus: This don't works, if we generated the url segment links with:

"./$page->name"

we never found that page with:

$codeChildName = "code--{$input->urlSegment1}"
$pages("name=$codeChildName")

because the page with that name doesn't exist

but looking at your proposal I found one solution:

add a "keyword" to the generated links and then remove that "keyword" after get that url segment.. works perfect!

this at the start of my template file:

<?php namespace ProcessWire; 

$wildcard = "-list";

if($input->urlSegment2) throw new Wire404Exception();

if($input->urlSegment1) {
	$request = $input->urlSegment1;
	}

if($request) {
	$name = str_replace($wildcard,"",$request);
	$name = $sanitizer->pageName($name);
	$codes_page = $pages->get("name=$name");
	if(!$codes_page->id) throw new Wire404Exception();
	} else {
	$codes_page = $page->child("include=all");
	}

?>

then when I generated the links in the template:

<?php foreach($page->children("include=all") as $child) { ?>
	<a href="<?=$child->name.$wildcard?>"><?=$child->title?></a>
<?php } ?>

and that's all.. it's ok? remember that I'm a graphic designer trying to coding

Link to comment
Share on other sites

I agree with bernhard that this situation is perfect for an ajax solution, but in the parent page I use a javascript plugin that need the markup from the child pages is present in the html output at document ready, not in the dom

Link to comment
Share on other sites

6 hours ago, Pixrael said:

I agree with bernhard that this situation is perfect for an ajax solution, but in the parent page I use a javascript plugin that need the markup from the child pages is present in the html output at document ready, not in the dom

Never said that ;) I would recommend reading my second link carefully and trying out markup regions :) (... And building your site with a template for your child pages instead of URL segments)

  • Like 1
Link to comment
Share on other sites

Quote

Your scientists were so preoccupied with whether or not they could, they didn’t stop to think if they should.

I strongly suggest creating a template for the child pages as well. You might not have an issue at the moment, but a month from now, a year from now, when you need to change something, it won't be where you expect it to be. It'll be harder to maintain. I had to do a number of complete rewrites in the past because I was only complicating things for myself for no reason.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...