Looking for a developer to fix the articles plugin

Hi everyone, I am looking for a modx developer to fix an issue with Articles.

The plugin automatically generate pages such as Author Page and the Tags Pages. But there is an important SEO issue with this:

Tag and Author pages are using the same title <title>, [[*longtitle]] and [[*pagetitle]] as the blog home page.

Ideally,
Author page should be like: “Articles by author
Tag page should be like: “Tag: TagName

The issue might actually come from getPage and getArchives plugins ( see here )

You will be pushing the fix directly to github ( I have open this issue here )

I also wanted to say is that you will also be helping the modx community by helping fixing the plugin! There are other people using articles ( I’m sure I’m not the only one :slightly_smiling_face: ).

Please, I would appreciate if you could make a precise offer ( how long and how much ).

P.S. If other people using articles are interested in fixing other issues as well ( there are a few on github ), we could set a crowfunding ( just an idea ).

If your problem is just, that all the pages (blog, author page, tag page) use the same template, then maybe you can add a snippet to this template that changes the output depending on the request variables that are present. Something like this may work:

Container template:

...
<title>[[!getPageTitle? &pagetitle=`[[*pagetitle]]`]]</title>
...

Snippet “getPageTitle”:

<?php
if (isset($_GET["tag"])){
    return "Tag: " . filter_var($_GET["tag"], FILTER_SANITIZE_STRING);
} else if (isset($_GET["arc_author"])){
    return "Articles by " . filter_var($_GET["arc_author"], FILTER_SANITIZE_STRING);
} else {
    return $pagetitle;
}
2 Likes

Hi @halftrainedharry thanks for your suggestion, I’ll try it and get back to you.

@joshualuckers do you think this could be implemented to articles ?

Hi @halftrainedharry , I have tried your solution and it seems to be working great! That’s amazing.

I have 2 questions though:

  • Is there a way to call the snippet cached ?
  • Would you be interested in implementing your solution to articles github page ? ( I would happily make a donation to your paypal account )

Thanks a lot anyways.

No. The output of the snippet depends on the request parameters that change between requests. This can’t be cached. But these few lines of codes shouldn’t take much time to execute.

The advantage of this approach is, that it can be implemented without changing the code of the Articles extra.

Honestly I’m not that familiar with the Articles source code and there is probably a better way to implement this. In my opinion it’s better to let the creator of the extra come up with a definitive solution and use this workaround in the meantime.

Here is an extended version of the snippet:

<?php
$title = $pagetitle;
$mode = 'normal';
$tag = '';
$username = '';

if (isset($_GET["tag"])){
    $mode = 'tag';
    $tag = filter_var($_GET["tag"], FILTER_SANITIZE_STRING);
    $title = "Tag: " . $tag;
} else if (isset($_GET["arc_author"])){
    $mode = 'author';
        
    //get username from database
    $user = null;
    $userprofile = null;
    $userPk = $this->xpdo->sanitizeString($_GET['arc_author']);
    if (function_exists('filter_var')) {
        $userPkNum = filter_var($userPk, FILTER_VALIDATE_INT);
    } else { 
        $userPkNum = intval($userPk); 
    }
    if ($userPkNum == 0) {
        $user = $this->xpdo->getObject('modUser', array('username' => $userPk));
    } else {
        $user = $this->xpdo->getObject('modUser', array('id' => $userPkNum));
    }
    
    if ($user){
        $userprofile = $user->getOne('Profile');
    }
    if ($userprofile) {
        $username = $userprofile->get('fullname');
    } else {
        $username = $userPk; //not in database
    }

    $title = "Articles by " . $username;
}

$modx->setPlaceholder('my.title', $title);
$modx->setPlaceholder('my.mode', $mode);
$modx->setPlaceholder('my.tag', $tag);
$modx->setPlaceholder('my.username', $username);
return '';

The snippet now creates placeholders (instead of returning the title) that can then be used in the template. It also returns the fullname of the user (instead of the username). Just call the snippet once uncached in the template. And maybe adjust the snippet to your specific needs.

Placeholders:

  • [[!+my.title]] → The page title as before (<title>[[!+my.title]]</title>)
  • [[!+my.tag]] → The current value of the tag (or '')
  • [[!+my.username]] → The current fullname of the user (or '')
  • [[!+my.mode]] → The values ‘normal’, ‘tag’ or ‘author’ depending on the request parameters. Can be used for output modifiers in the template:

[[!+my.mode:select=`normal=[[*pagetitle]]&tag=Tag: [[!+my.tag]]&author=Articles by [[!+my.username]]`]]

5 Likes

Hi @halftrainedharry again thanks a lot for your help.

I actually realised this would be fairly easy to implement into articles.
All the template/snippets are stored here:

I’m gonna try to submit your solution and see how it goes.

Hi everyone,

I’m bumping this old topic because I’ve realised there might be a bug with MODX Articles. Basically, you can generate any page you want by adding this URL to any articles-based blog:

?arc_author=somerandomwords&page=2

Instead of returning an error page, Articles actually generates these pages.

It gets worse when using the script above, as it displays these random words on the website.

Any ideas on how to fix this?

I was thinking of maybe forcing the script to check for the author or tag existence, but it’s just a temporary fix. Articles should not be generating these pages.


This is the script by @halftrainedharry that I have slightly modified:

getPageTitle

<?php
if (isset($_GET['tag'])) {
	return 'Tag: ' . htmlspecialchars($_GET['tag'], ENT_QUOTES, 'UTF-8');
} else if (isset($_GET['arc_author'])) {
	return 'Articles by ' . htmlspecialchars($_GET['arc_author'], ENT_QUOTES, 'UTF-8');
} else {
	return htmlspecialchars($pagetitle, ENT_QUOTES, 'UTF-8');
}

getPageDescription

<?php
// Default to the resource description if no specific parameters are found
$description = $description ?: '';

// Check if the 'tag' parameter exists in the URL
if (isset($_GET['tag'])) {
	$description = 'Explore articles tagged with ' . htmlspecialchars($_GET['tag'], ENT_QUOTES, 'UTF-8');
}
// Check if the 'arc_author' parameter exists in the URL
else if (isset($_GET['arc_author'])) {
	$description = 'Read articles written by ' . htmlspecialchars($_GET['arc_author'], ENT_QUOTES, 'UTF-8');
}
// Return the final description
return $description;

Not sure if Articles is still the way to go for a blog…

For MODX 3+ I would suggest using Collections with PDO Resources and if needed Tagger.

1 Like

Is this really a problem?
The page outputs a list of articles and with request-parameters for author or tag you can filter this list. If you supply a value that doesn’t exist, then the list is simply empty or the unfiltered list gets returned.

You obviously don’t want to output HTML or JS input from a user directly to your page, but you can achieve that by properly sanitizing the user input.


What exactly do you want to happen?

  • Only show the page if a user exists?
  • Or only show the page if an article exists written by this user?

In the first case, you can just check the modUser table (see my code above for the “extended version”) and forward the request to the error page if a corresponding user can’t be found.

In the second case, you’d have to evaluate the output of the getPage/getResources call that happens on the page.

Apologies for my late reply, somehow I missed the notifications.

@AnyScreenSize If I switch to Collection, will I be able to maintain the tags and URL format that were already created by articles ?

@halftrainedharry I managed to make some changes to the snippet, and it seems to have fixed the issue.

No problem!

  • Tags will be needed to be exported somehow and converted to the more modern Tagger
  • URL format should be problem no
1 Like

Yes, I’ll probably run some tests locally first, from experience, there’s always something that goes wrong :laughing:. Never make big changes directly on a live website!

But yes, I will check that out.