Leaderboard
Popular Content
Showing content with the highest reputation on 02/10/2025 in all areas
-
There we are: https://ddev.readthedocs.io/en/latest/users/quickstart/#processwire-zip-file 💖2 points
-
This hook is used to monitor file changes and page updates in your ProcessWire project. It operates when debug mode is active and returns file changes and latest page update information in JSON format. The script hook is automatically injected before the </body> tag in your HTML. It periodically checks for any file or page updates in your system at the interval you specify. If the previous check time is older than the new check time (indicating changes), the page automatically refreshes. ~/site/ready.php if ($wire->config->debug) { $wire->addHookAfter('Page::render', function (HookEvent $event) { $script = <<<HTML <script> const browserSync = { mtime: 0, init() { this.sync(); }, sync() { fetch('/browser-sync') .then(response => response.json()) .then(data => { if (!this.mtime) { this.mtime = data.max; } else { if (data.max > this.mtime) { location.reload(); } } }); } }; browserSync.init(); setInterval(() => browserSync.sync(), 2500); </script> HTML; $event->return = str_replace('</body>', "{$script}</body>", $event->return); }); $wire->addHook('/browser-sync', function (HookEvent $event) { $wire = $event->wire(); $root = $wire->config->paths->root; $siteRoot = $wire->config->paths->site; $extensions = '*.{php,js,css}'; $paths = [ "{$root}src/{$extensions}", // custom composer package "{$root}src/src/{$extensions}", // custom composer package "{$siteRoot}{$extensions}", // ready.php, init.php, finished.php "{$siteRoot}classes/{$extensions}", // page classes "{$siteRoot}templates/{$extensions}", "{$siteRoot}templates/*/{$extensions}", "{$siteRoot}templates/*/*/{$extensions}", "{$siteRoot}templates/*/*/*/{$extensions}", "{$siteRoot}templates/*/*/*/*/{$extensions}", ]; $files = []; foreach ($paths as $pattern) { // Try with GLOB_BRACE first $result = glob($pattern, GLOB_NOSORT | GLOB_BRACE); // If no results with GLOB_BRACE, try without it if (!$result) { $result = glob($pattern, GLOB_NOSORT) ?: []; } $files = array_merge($files, $result); } $filemtime = 0; foreach ($files as $file) { if (!is_file($file)) { continue; } try { $mtime = @filemtime($file); if ($mtime && $mtime > $filemtime) { $filemtime = $mtime; } } catch (\Exception $e) { continue; } } $latest = $wire->pages->get('sort=-created|-modified'); $latestTime = $latest->modified > $latest->created ? $latest->modified : $latest->created; header('Content-Type: application/javascript'); echo json_encode([ 'max' => max($filemtime, $latestTime), 'mtime' => $filemtime, 'modified' => $latest->modified, 'created' => $latest->created ]); exit; }); } This development tool helps streamline your workflow by automatically refreshing the browser when you make changes to your files or content, eliminating the need for manual page refreshes during development.1 point
-
was just about to delete my comment! I just realised that I hadn't updated the module. updated and all good, works as you say with pipe seperator in multi language field. Thanks so much!1 point
-
Good. Read my answer there for ckeditor (no idea for tinymce):1 point
-
Hello everyone, Some of you may already be working with DDEV, and probably some of you are familiar with Tailscale as well. Just briefly: Tailscale is, and I’ll try to be as sober as possible, a gift from the heavens. It’s a type of mesh VPN and ridiculously easy to install and manage. It's free for up to 100 clients, too. Please just check out a few videos on YouTube about it, it’s a lot of fun to work with. In broad strokes, it works like this: You sign up – for example – with Google Auth at tailscale.com. Then you install – for example – the client for your Mac (it’s available for nearly all operating systems). You also install the client on your home server. (In my case, Tailscale is also running on my Synology, and there are some great guides for that.) A rough outline of the workflow: (For installation details and the necessary steps, Perplexity was a huge help. LLMs are truly a blessing for this kind of thing; there are nice step-by-step guides.) I still had a Dell Optiplex 7050 lying around (these things cost about 100 euros, they’re very quiet and energy-efficient). I also had some extra RAM, and I installed a 1 TB NVMe. I installed Debian 12 netinstall and then added all the necessary packages. Those include: Docker, DDEV, Tailscale (https://tailscale.com/kb/1031/install-linux) After a successful installation, you'll be prompted in the console: To authenticate, visit: https://login.tailscale.com/a/XXXXXXXXXXXXXXX Open the URL in your browser and log in using the same auth method – for me, that’s Google in all cases. And just like that, your server has joined your Tailscale network and gets an IP in the format 100.x.y.z and tailxxxx.ts.net. Docker and DDEV should already be running smoothly before proceeding. To make Docker listen to the Tailscale IP, you'll need to add the following to /etc/docker/daemon.json: { "hosts": ["fd://", "tcp://100.x.y.z:2375"] } This may vary in your case, but the idea should be clear. On my laptop, I use VSCode, and I’ve also installed the "VSCode Remote SSH Extension" to handle everything remotely. My specific workflow now is that I log into the server with the IDE, and for example, under /home/$USER/sites/$project, I start a new DDEV project. You know the drill: ddev config, ddev start, and so on... Now, to access the newly created projects from my client (here, a MacBook) without constantly editing the hosts file, I installed dnsmask via brew. In the default installation, you can edit the dnsmask.conf via nano: nano /opt/homebrew/etc/dnsmasq.conf And there, please add: address=/.ddev.site/100.x.y.z Then run: sudo brew services restart dnsmasq Et voilà, that’s it. Your example.ddev.site is now directly accessible. This might be a bit rough around the edges, but you’re professionals, and the idea should be clear. It has greatly improved my workflow, and I no longer have to worry about securing my server, since it’s only accessible from my Mac, no matter where I am, while my project data is safe on my home server. I hope you'll have as much fun with it as I have! 😀1 point
-
Hello There Fellow PW lovers. I wanted to share this code that i created to post tweets to the Twitter API in an upcomming project i am working on. And i Thought that everyone could have some use for it. I am using Composer to load the TwitterOAuth PHP library for working with the Twitter API in this code example. Also you need to create an App and have your own API keys ready, you can do that here: https://developer.twitter.com/en/apps The code posts a string and uploads media to be used with the tweet. For the TwitterOAuth methods information see the link above. Note: The paths to the media needs to be local for TwitterOAuth to pick them up and upload them. See this link for filesize limits and other info on media attachements. https://developer.twitter.com/en/docs/media/upload-media/overview <?PHP /* TwitterOAuth API via Composer https://twitteroauth.com/ */ include('vendor/autoload.php'); /* define the classes */ use Abraham\TwitterOAuth\TwitterOAuth; function postTweetUpdate($str = '', $mediaArray = null) { /* Twitter OAuth keys Create your App and find your API keys here: https://developer.twitter.com/en/apps */ $consumer_key = ''; $consumer_secret = ''; $access_token = ''; $access_token_secret = ''; /* init API */ $connection = new TwitterOAuth($consumer_key, $consumer_secret, $access_token, $access_token_secret); if(is_array($mediaArray)) { $mediaIDS = array(); /* Up to 4 media objects can be uploaded. https://developer.twitter.com/en/docs/media/upload-media/overview */ foreach($mediaArray AS $key => $media_path) { /* Upload media to twitter API and get media ID back */ $mediaOBJ = $connection->upload('media/upload', ['media' => $media_path]); /* push uploaded media ID to array */ array_push($mediaIDS, $mediaOBJ->media_id_string); } /* create comma delimited list of media ID:s */ $mediaIDstr = implode(',', $mediaIDS); } /* API params */ $arrayCfg['status'] = $str; $arrayCfg['media_ids'] = $mediaIDstr; /* Make POST request to Twitter API https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update */ $statuses = $connection->post("statuses/update", $arrayCfg); /* return payload */ return $statuses; } ?> <?PHP /* string to Post */ $str = 'Test Tweet... ' . PHP_EOL; $str .= '#mytweet' . PHP_EOL; $str .= 'http://www.mywebsite.com' . PHP_EOL; $str .= '' . hash('sha1', mt_rand(0, 1000000)); /* media to upload */ $mediaToUpload[] = 'images/my_image.jpg'; /* make request to Twitter API */ $payLoad = postTweetUpdate($str, $mediaToUpload); ?> <h3>Debug</h3> <pre><?PHP print_r($payLoad); ?></pre> I have the Debug part because its handy to see what is returned from the Twitter API.1 point
-
hey kixe, also the best wishes to you would you mind doing a short screencast so that we do not have to install it, create the fields etc... http://www.cockos.com/licecap/ is a cool small tool to do that in seconds on win/osx. it creates a GIF so you don't even have to upload it to youtube or the like. just record and post it directly here in the forum. thank you for sharing your module1 point