Jump to content

Leftfield

Members
  • Posts

    109
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by Leftfield

  1. Thanks @Pete! I will add hidpi image latter. Never did it before but now hitting my head... Yes, pricing wasn't exactly a walk in the park. But after years of wrestling with enough SEO nightmares on WordPress and Shopify to fill a horror novel (weird canonical URLs, ghost broken pages, and sitemaps that would make Einstein cry), I think it's safe to say this calls for a celebratory dance.
  2. Hey @dotnetic thanks for the feedback! Thank you very much!!! Will fix first thing in the morning (hopefully)
  3. I had some primitive code with JavaScript (ugly enough to scare small children) and I decided to make a proper module. I've touched it, of course, and now it's organized chaos. I have issues (yea, me like a person, and the code): It wont create json file. It wont write to json file even I manually created one. It loads data from the backend pages even I am trying to avoid that. And it is working when you DO NOT reload. <?php namespace ProcessWire; class UrlTracker extends WireData implements Module { private $logFilePath; public static function getModuleInfo() { return array( 'title' => 'URL Tracker', 'version' => 1, 'summary' => 'Tracks specified tracking parameters and logs to monthly JSON files.', 'href' => 'https://vujosevic.com', 'author' => 'Leftfield', 'requires' => array('ProcessWire>=3.0.0'), 'icon' => 'link', 'autoload' => true, 'permissions' => array(), 'installs' => array(), ); } public function init() { // Ensure the tracking directory exists $trackingDir = $this->config->paths->assets . 'tracking/'; if (!is_dir($trackingDir)) { if (mkdir($trackingDir, 0777, true)) { $this->wire('log')->save('url-tracker', "Created tracking directory: $trackingDir"); } else { $this->wire('log')->save('url-tracker', "Failed to create tracking directory: $trackingDir"); } } $this->logFilePath = $trackingDir . 'url_tracker_log_' . date('Ym') . '.json'; $this->addHookAfter('ProcessPageView::execute', $this, 'trackVisitedURL'); $this->wire('log')->save('url-tracker', 'URLTracker module initialized.'); } public function ___install() { $this->wire('log')->save('url-tracker', 'URLTracker module installed.'); } public function ___uninstall() { $this->wire('log')->save('url-tracker', 'URLTracker module uninstalled.'); } public function trackVisitedURL($event) { $pageID = $event->arguments(0); // Fetch the Page object from the page ID $page = $this->pages->get((int)$pageID); // Check if $page is indeed a Page object if (!$page instanceof Page || !$page->id) { $this->wire('log')->save('url-tracker', "No valid Page object provided. Argument: " . print_r($pageID, true)); return; } // Check if the current page is not an admin page if ($this->wire('page')->template->name === 'admin' || $page->parent()->id == $this->wire('config')->adminRootPageID) { $this->wire('log')->save('url-tracker', "Page is part of admin: {$page->title}"); return; } $input = $this->wire('input'); $url = $input->url; // Log the URL $this->wire('log')->save('url-tracker', "trackVisitedURL called for URL: $url"); // Check if the page is not hidden if (!$page->isHidden()) { $this->wire('log')->save('url-tracker', "Page is visible and published: {$page->title}"); // Check if the URL contains any of the specified tracking parameters if (strpos($url, 'track=email') !== false || strpos($url, 'track=x') !== false || strpos($url, 'track=facebook') !== false || strpos($url, 'track=linkedin') !== false) { $this->wire('log')->save('url-tracker', "URL contains tracking parameter: $url"); // Log to JSON file $this->logToJSON($url); } else { $this->wire('log')->save('url-tracker', "URL does not contain tracking parameter: $url"); } } else { $this->wire('log')->save('url-tracker', "Page is hidden: {$page->title}"); } } private function logToJSON($url) { $logFilePath = $this->getLogFilePath(); $logEntry = array( 'url' => $url, 'timestamp' => array( 'year' => date('Y'), 'month' => date('m'), 'day' => date('d'), 'hours' => date('H'), 'minutes' => date('i'), 'seconds' => date('s'), ), ); // Read the log $logData = []; if (file_exists($logFilePath)) { $logData = json_decode(file_get_contents($logFilePath), true); } // Add new entry $logData[] = $logEntry; // Write log data if (file_put_contents($logFilePath, json_encode($logData, JSON_PRETTY_PRINT))) { $this->wire('log')->save('url-tracker', "Logged URL to JSON: $url"); } else { $this->wire('log')->save('url-tracker', "Failed to log URL to JSON: $url"); } } private function getLogFilePath() { $currentMonth = date('Ym'); $logFilePath = $this->config->paths->assets . 'tracking/url_tracker_log_' . $currentMonth . '.json'; return $logFilePath; } }
  4. That's a good point, but it is literary intended for blocking ads. That's why I am using it: to check that my popups are working, etc. For the cookies, there is a setting in the browser (and this module has it in its settings) to send "Do not track." For anyone with the same issue, I used custom classes and fixed an issue. Changed the name of classes which starts with privacywire and the word banner. @Kholja thanks again!
  5. Yep, that was it. THANKS!!!!!!! Now I need to figure out how to go around it. Thanks once again.
  6. @Kholjamate, try to explain to my customer who knows GDPR better than any lawyer, online audits and all AI tools.
  7. Hey @joshua Thanks for this wonderful module! I think I found some kind of bug, IDK. I am using ProcessWire 3.0.229 and PHP 8.1. Your module Privacy Wire is the latest version: 1.1.6 The Brave browser doesn't want to show the banner at all. I've attached a screenshot. Deleted cache and cookies and tested in Chrome, Firefox, Edge, and Opera. I have no idea where to look for the "problem" in the code.
  8. Hi @All, Hey @David Karicha great module!!! I mean, the possibility of tracking keywords is speechless... I've updated my botlist.txt file with this: go-http-client|googlebot|bingbot|link|googlebot-image|yandexbot|semrushBot|ahrefsBot|zoominfobot|applebot|seznambot|yak-linkfluence|barkrowler|blexbot|yandeximages|cfnetwork|linkedinbot|feed|dalvik|validator|baiduspider|2345Explorer|survey|surdotlybot| But I am not sure how to add: "Screaming Frog SEO Spider" with empty spaces between words. Thanks!
  9. Hi @All, Please, and I've tried really hard to find this but I can't: How can I implement this module with the default ProcessWire cookie? I need Reject All Cookies option.
  10. Hey @ryanThanks for the Autolinks module! I thought about making something like this :D but I am laughing at myself and my abilities. Is there a dedicated Forum page for it (I couldn't find one), or will there be one? I wouldn't like to change the code manually because of future updates, but I would like to discuss some features I think the module should have, like adding an option for choosing templates (or excluding them) where it should work. It is uber important from an SEO point of view to control where links come from and to what pages. The architecture of inner linking is a really important signal.
  11. Yes @wbmnfktr (now I count bottles of whiskey I own you), I am on my mobile, waited to come home to sit down by the computer to post here, but you posted before me. In the end, I found out it was my server blocking the outgoing SMTP connection. The module is working great! Still waiting the host to unlock it.
  12. Hello @All I got a problem. Latest PW, same PHP 8.1 When sending from Localhost everything is working fine. When sending from my website I got "Connection refused". Error log: module/edit?name=WireMailSmtp&collapse_info=1 Error in hnsmtp::send : cannot connect to smtp-server! I've tried to change Hostname of this computer but no luck. Using smtp.zoho.com, port 465, SSL checked
  13. @kixethat's a great solution!!! But, reducing database queries is a priority for me. So, here's a straightforward approach to prevent bloating: Example: I use a button with descriptions on various parts of the different pages. I needed a simple solution to change everything in one place, not to edit every page. So I made global-button.php (and more similar files for the same purpose) and called it wherever it needed to be with <?php include('global-button.php'); ?> So now I have only one page to edit, and voila. Hope this will help someone.
  14. Yes, it is a custom (multilingual-ready) module. I thought I would write a solution here when I found a fix.
  15. My whole website is messed up. When I was installing modules for multilanguage support, I got the following errors: PHP 8.1.0 ProcessWire: 3.0.229 On the front: Warning: foreach() argument must be of type array|object, null given in ...\wire\modules\LanguageSupport\LanguageSupportPageNames.module on line 126 In the backend: Warning: foreach() argument must be of type array|object, null given in ...\wire\modules\LanguageSupport\LanguageSupportPageNames.module on line 126 Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given in ...\wire\modules\LanguageSupport\ProcessLanguage.module on line 340 ( ! ) TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given in ...\wire\modules\LanguageSupport\ProcessLanguage.module on line 340
  16. Hi Alexander, can you please help me? I got an email to mark the post (it is yours) to mark it as the solution. I am looking for the last hour where it is the button but I have no idea. Do you know?

    1. wbmnfktr

      wbmnfktr

      Go to the first post, click on edit and add [SOLVED] to the beginning of the title and that will do it.

  17. I've just tried and it worked like a charm. I will go nuts
  18. Hey @ceberlin thanks!!! I thought to do it anyway and add more functionalities in the next update. For now, change the function checkTextLength in SeoTextWidth.js // Text length checking and warning (updated) function checkTextLength(input, fieldConfig) { const span = $('<span class="detail"></span>').insertAfter(input); input.keyup(function() { const text = $(this).val(); const width = Math.round(calculateTextWidth(text, fieldConfig.font)); // Round to whole number if (width > fieldConfig.maxWidth) { span.html(`<i class="fa fa-exclamation-circle"></i> <span class="text-danger">Warning:</span> Text exceeds max width (${fieldConfig.maxWidth}px).`); span.addClass('text-danger'); } else { span.text(`Estimated Width: ${width}px`); // Display rounded value span.removeClass('text-danger'); } }); }
  19. @BrendonKozNo. The Validator validated every 10th time. Once, the tweet pulled the full image. Once, it created space but an empty image. Several times, it created a thumbnail with no image, too. I will try HTML and another server tomorrow first thing in the morning. I tried from the same server, another website in ProcessWire, and it worked. Not anymore. (edit) I tried with another CMS from another server; it was a different CMS, and it worked.
  20. @BrendonKozI've tried that. But I'm going to try it again right now and will let you know. Thanks for the effort, mate!
  21. @BrendonKozthanks for helping me!!! I've tried the non-minimized version (it worked before as-is). I even changed the brackets at the end from "/>" to ">" and back. It's incredibly frustrating because I have no idea what to do, and I'm not server-oriented enough to test it from that side, like ports. I believe I've missed something, but I can't see it.
  22. I don't want to share a link here (it is my signature), but I have a problem: when sharing a link on Twitter (X), it doesn't pull images anymore. The problem started "recently," and I can't replicate it. I rewrote the code, removed it, and placed it again, cleared the cache every time, tried with meta twitter:image:src, had a look at the cpanel (no IP blocked), read about 100 websites, and I am completely powerless. I hoped someone here could help me. I got the following error when using the Twitter Card Validator: ERROR: Failed to fetch page due to: HttpConnectionTimeout
  23. It is ready. Sorry for the second post. Kind regards and thanks!
×
×
  • Create New...