Diffrent Content by URL Paramter

Hello,
I have a resource and would like to display different content in a special area, similar to the blog.

So in the resource [50]
ts landing page
with the addition
ts-landingpage?city=city1
additional content from a sub-resource e.g. [51]

or
ts-landingpage?city=city2

additional content from a sub-resource e.g. [52]

Did I use tagger here, or urlparam + get page?

I’ve just lost something and would be happy to get some help or advice.

Thanks
chrissen

If the purpose is to display the content of different sub-resources, it’s probably easier to use getResources and an URL parameter.

With Tagger, you’d have to create a new unique tag for every single sub-resource, which is a bit cumbersome and pointless.


If you want nicer URLs like for example ts-landingpage/city1 or ts-landingpage/city2, you could maybe use the extra CustomRequest.

1 Like

thanks for the quick reply.

But I think I would have to work with renderResources.
Since standard content can be seen on the resource (50) ts-landingpage and with the url parameter =cityname (hamburg, berlin…) a special content should come at the end. I wanted to outsource it to sub-resources (51, 52…) that can be maintained there via content-blocks.

I’m currently looking for a technical approach to solve this. possibly a TV for the city residents, but how can use renderresource depending on the url-param ?=cityname > res-id51, 52 …?

Why do you think you have to use renderResources for that, instead of getResources or pdoResources?

All these snippets (renderResources/getResources/pdoResources) have the properties &where and &tvFilters that can be used to filter the output. The value of these properties can be generated dynamically in a snippet, depending on the GET parameter.


Not sure I understand what you trying to do here exactly.
Do you want to filter the cities by population size?

I sketched it once


Ok, so where are the city names stored in the sub-resources (that are used as the values of the GET parameter “city”)?
Depending on if it’s a resource field or a TV, the code will be slightly different.

Here I assume that the city name is stored in the resource field “alias”.


You could (for example) use a solution like this (using pdoResources from pdoTools):

<!-- In the resource 50 -->
[[!pdoResources?
    &tpl=`@INLINE <section>[[+content]]</section>`
    &where=`[[!createWhereFilter]]`
    &includeContent=`1`
]]

Custom snippet “createWhereFilter” to dynamically create the where property for pdoResources:

<?php
if (isset($_GET['city'])) { // Does the GET parameter 'city' exist?
    $city = filter_var($_GET['city'], FILTER_SANITIZE_STRING); //Read the parameter value
    // Maybe do some additional sanitization ...
    
    $filter = ['alias' => $city]; // filter by the 'alias' resource field
    return json_encode($filter); // JSON encode the filter-array
}
return '';

What should be shown in resource 50 when there is no GET parameter “city”?

The solution I posted above outputs the content of all the sub-resources.
If you want to output nothing (when there is no GET parameter “city”), you could instead use something like this:

<!-- In the resource 50 -->
[[!showCity]]

Custom snippet “showCity”

<?php
if (!isset($_GET['city'])) { // Does the GET parameter 'city' exist?
    return ''; // Don't output anything if there is no parameter 'city'
}

$city = filter_var($_GET['city'], FILTER_SANITIZE_STRING); // Read the parameter value
// Maybe do some additional sanitization ...

$filter = ['alias' => $city]; // filter by the 'alias' resource field

// Run the snippet 'pdoResources' and return the result
return $modx->runSnippet('pdoResources', [
    'tpl' => '@INLINE <section>[[+content]]</section>',
    'includeContent' => true,
    'where' => $filter
]);

Hey @halftrainedharry,

thanks for Support. The first solution with the createWhereFilter snippet throw out all sub-resources, like you say in your secound post.

the second way shows nothing.

i have an Ressource: hannover > with ressource-alias hannover
Screenshot 2024-07-05 at 08-59-22 Bearbeite hannover
domain.de/hannover show sthe content

i create the snippet showCity with your example code for the url-param and pdoRes

pdoTools is installed

tested with [[!showCity]] in the ressource 50, and [[showCity]] in the template is id 50…

i got no output form the hannover ressource by using: ts-landingpage?city=hannover

Did I miss something or do something wrong?

Not sure why it doesn’t work.
You could add some log messages ($modx->log(...)) to the snippet showCity to maybe better understand what’s going on:

<?php
if (!isset($_GET['city'])) { // Does the GET parameter 'city' exist?
    $modx->log(modX::LOG_LEVEL_ERROR, 'no GET parameter "city"');
    return ''; // Don't output anything if there is no parameter 'city'
}

$city = filter_var($_GET['city'], FILTER_SANITIZE_STRING); // Read the parameter value
$modx->log(modX::LOG_LEVEL_ERROR, 'value of GET parameter "city" = ' . $city);
// Maybe do some additional sanitization ...

$filter = ['alias' => $city]; // filter by the 'alias' resource field

// Run the snippet 'pdoResources' and return the result
$output = $modx->runSnippet('pdoResources', [
    'tpl' => '@INLINE <section>[[+content]]</section>',
    'includeContent' => true,
    'where' => $filter,
    'setTotal' => true
]);

$total = $modx->getPlaceholder('total');
if ($total == 0){
    $modx->log(modX::LOG_LEVEL_ERROR, 'no resource found with alias = ' . $city);
}

if (empty($output)) {
    $modx->log(modX::LOG_LEVEL_ERROR, 'no content to return');
}

return $output;

Make the request in the frontend (ts-landingpage?city=hannover), then check the MODX error log to see what gets logged.


Always call the snippet uncached (with the !) → [[!showCity]]

Cache or temp Problem?
core/cache is writable and full of actually Data
PHP session path problem?

Here the Logs

core/src/Revolution/modResponse.php : 184) PHP warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: /var/lib/php/sessions, handler: write)
core/cache/includes/elements/modx/revolution/modsnippet/43.include.cache.php : 3) no GET parameter "city"

The session writing problem seems to be a different issue (and shouldn’t affect the snippet “showCity”).

So the code can’t find the GET parameter “city” → $_GET['city'].

  • Do you request the page (where “showCity” runs) with the parameter added to the URL → ?city=hannover?
  • Is there maybe some redirect (or rewrite) that happens, that leads to the loss of the GET parameters?
1 Like

it runs! perfect :slight_smile:

Do you request the page (where “showCity” runs) with the parameter added to the URL → ?city=hannover?

yes= /ts-landingpage?city=koeln & /ts-landingpage?city=hannover

Shows the different content from the Sub-Ressources in (id50) ts-landingpage

the [[!showCity]] is in my Master Template is ID 50 = [[!showCity]], not in the Ressource itselfs.

Result in Log

(ERROR @ /core/cache/includes/elements/modx/revolution/modsnippet/43.include.cache.php : 8) value of GET parameter "city" = koeln

(ERROR @  /core/cache/includes/elements/modx/revolution/modsnippet/43.include.cache.php : 8) value of GET parameter "city" = hannover

is use this Version

<?php
if (!isset($_GET['city'])) { // Does the GET parameter 'city' exist?
    $modx->log(modX::LOG_LEVEL_ERROR, 'no GET parameter "city"');
    return ''; // Don't output anything if there is no parameter 'city'
}

$city = filter_var($_GET['city'], FILTER_SANITIZE_STRING); // Read the parameter value
$modx->log(modX::LOG_LEVEL_ERROR, 'value of GET parameter "city" = ' . $city);
// Maybe do some additional sanitization ...

$filter = ['alias' => $city]; // filter by the 'alias' resource field

// Run the snippet 'pdoResources' and return the result
$output = $modx->runSnippet('pdoResources', [
    'tpl' => '@INLINE <section>[[+content]]</section>',
    'includeContent' => true,
    'where' => $filter,
    'setTotal' => true
]);

$total = $modx->getPlaceholder('total');
if ($total == 0){
    $modx->log(modX::LOG_LEVEL_ERROR, 'no resource found with alias = ' . $city);
}

if (empty($output)) {
    $modx->log(modX::LOG_LEVEL_ERROR, 'no content to return');
}

return $output;

@halftrainedharry
I have changed the snippet so that if a city does not require any special content (then no city=cityname parameter is used) a resource with standard content is loaded (the LP standard).

I’m just writing in case someone is reading this and has a similar construction site.

Thanks again for the support, it’s running great now and we’ve solved the cache problem too.

<?php
if (!isset($_GET['city'])) {
    return '';
}

$city = filter_var($_GET['city'], FILTER_SANITIZE_STRING);

$output = $modx->runSnippet('pdoResources', [
    'tpl' => '@INLINE <section>[[+content]]</section>',
    'includeContent' => true,
    'where' => ['alias' => $city],
    'setTotal' => true
]);

if ($modx->getPlaceholder('total') == 0 || empty($output)) {
    $output = $modx->runSnippet('pdoResources', [
        'tpl' => '@INLINE <section>[[+content]]</section>',
        'includeContent' => true,
        'where' => ['alias' => 'lp-standard'],
    ]);
}

return $output;
1 Like

This topic was automatically closed 2 days after discussion ended and a solution was marked. New replies are no longer allowed. You can open a new topic by clicking the link icon below the original post or solution and selecting “+ New Topic”.