Leaderboard
Popular Content
Showing content with the highest reputation on 08/02/2023 in all areas
-
After 9 years using ProcessWire I still do multiple times a day a typo writing template as tempalte (probably write it wrong more often than right). I know few of my co-workers does the same. Is this curse for us Finnish people, or is tempalte thing in other parts of the world also?1 point
-
Hi @protro I didn't read the thread linked, but I will try to give a small insight of how I am used to dev with ProcessWire, and a note of ES6+ modules, with the answer of the import statements error, I will give you a starter module too at the end of this thread. And sorry, I have to be quick, so I am posting screenshot instead of a good formatted post, see the setup image at the end. First, there is nothing wrong about using a package manager like node/npm, but you should do it in order to make you the life easier. It's more true when working with all the crypto mess. A word on your previous message, almost all lib/packages are developed using JS (TypeScript) so it will work with quite every frameworks/libs (React, Svelte, Vue, whatever). Some implementation are specialized for React, not surprising, React is in JS world what Wordpress is in the PHP world (check the stats in the linked thread below, fellow members here seem to not used it, hooray, react syntax is weird and slow). My setup of almost every app (stay tuned as the whole things are coming published for free): About the ES6+ module, when working with them, you need to use JS and for production building the app, OR you can call them in your `<script></script>` by setting up the script as module by writing `<script type="module"></script>`. Keep in mind that writing calls like that in templates, make global objects, like window, not available until the document is ready making things like binding events to DOM a bit tiresome.. And a draft of a module. It should not work as is, but it's just to give you an "image" more than words and could be written in templates. Writing JS like that (module or template) is not the better way to do it, and should be avoided, it makes things complicated when they're actually quite simple, even more when speaking about Metamask. Check the method `writeWeb3ModalScript()`, you can see that libs can be used from a CDN when published (unpkg make automatically available dist files of any packages): <?php namespace ProcessWire; class Web3 extends WireData implements Module, ConfigurableModule { const WEB3MODAL_PROJECT_ID = ''; // read from db or .env file const ALCHEMY_API_KEY = ''; // read from db or .env file public static function getModuleInfo() { return [ 'title' => 'Web3', 'version' => '0.0.1', 'summary' => 'Web3 for ProcessWire', 'autoload' => false, 'icon' => '', 'requires' => [], 'installs' => [], ]; } public function writeWeb3ModalScript($buttonDomID) { $scriptTag = <<<EOT <link rel="stylesheet" href="https://unpkg.com/@rainbow-me/rainbowkit@1.0.7/dist/index.css" /> <script type="module"> import Onboard from 'https://unpkg.com/@web3-onboard/core' import injected from 'https://unpkg.com/@web3-onboard/injected-wallets' window.onload = async function() { const MAINNET_RPC_URL = 'https://mainnet.infura.io/v3/[APIKEY-HERE]' const onboard = Onboard({ wallets: [injected], chains: [ { id: '0x1', token: 'ETH', label: 'Ethereum Mainnet', rpcUrl: MAINNET_RPC_URL } ] }) const wallets = await onboard.connectWallet() console.log(wallets) const connectButton = document.getElementById("$buttonDomID"); // 3. Sign In window.onSignIn = function() { console.log(connectButton); console.log(window, window.onSignIn); } } </script> EOT; return $scriptTag; } // wallet can be an ENS formatted address public function getTokensForWallet($wallet) { $url = "https://eth-mainnet.g.alchemy.com/nft/v3/" . self::ALCHEMY_API_KEY; $url .= "/getNFTsForOwner?owner=" . $wallet; // send get request to alchemy api $http = new WireHttp(); $response = $http->getJSON($url); return $response; } // two fields in the backend /** * Config inputfields * * @param InputfieldWrapper $inputfields */ public function getModuleConfigInputfields($inputfields) { $modules = $this->wire()->modules; /** @var InputfieldFieldset $fs */ $fs = $modules->get('InputfieldFieldset'); $fs->label = $this->_('API Configuration'); $inputfields->add($fs); /** @var InputfieldCheckbox $f */ $f = $modules->InputfieldText; $f_name = 'web3modal_project_id'; $f->name = $f_name; $f->label = $this->_('Web3Modal Project ID'); $f->description = $this->_('Get Key there: https://cloud.walletconnect.com'); $f->columnWidth = 50; $f->value = $this->web3modal_project_id; $fs->add($f); /** @var InputfieldText $f */ $f = $modules->InputfieldText; $f_name = 'alchemy_api_key'; $f->name = $f_name; $f->label = $this->_('Alchemy API Key'); $f->description = $this->_('Get Key there: https://dashboard.alchemy.com'); $f->columnWidth = 50; $f->value = $this->alchemy_api_key; $fs->add($f); } } (The NPM package is still not available publicly, but not fully required) I will come back later with a working example using a CDN and a small example of a built js app working with PW. In the meantime, I'll leave you to ponder.1 point
-
Use something like this: <?php wireIncludeFile($page->type_menu); ?> What exactly do you have in the "type_menu" field? You have to make sure that only your desired files can be accessed/included! Perhaps it is also better to map this via a switch/case - perhaps an if is enough: <?php if($page->type_menu == "menu-A") { wireIncludeFile('styles/menu-A.php'); } else { wireIncludeFile('styles/menu-B.php'); } ?>1 point
-
It occurs to me that if you want a single expression you could also use: if($page->get("field_$i") == 'test') { ...1 point
-
Sometimes you need to execute a slow task after some event occurs in the PW admin, and normally you have to wait for this task to finish before you can continue using the admin. This is because PHP is "blocking", meaning that while one thing is executing nothing else can execute. There are potentially lots of different kinds of tasks that could be slow, but just as an example suppose you want to generate resized variations of images on a page, and there are a lot of images. You might have a hook like this so that any non-existing variations are created when the page is saved: $pages->addHookAfter('saveReady', function(HookEvent $event) { /** @var Page $page */ $page = $event->arguments(0); // When a gallery page is saved if($page->template == 'gallery') { // Create an image variation for each image foreach($page->images as $image) { $image->size(1200, 1200); } } }); When you save a gallery page in the PW admin, the admin will be unresponsive and will only load again after all the variations have been created. I wanted to find a way for slow tasks to be triggered by events in the PW admin and for the website editor not to have to wait for the task to finish before continuing with other work in the admin. Inspired by this StackOverflow answer I came up with the following solution that seems to work well. Using the image variations task above as an example... First we make use of the URL hooks feature to set up a URL that can trigger tasks to run when it is loaded: // A URL that will trigger tasks when loaded $wire->addHook('/run-task/', function($event) { $input = $event->wire()->input; // A simple check to avoid unauthorised access // You could implement more advanced checks if needed if($input->post('key') !== 'cTdPMBQ7x8b7') return false; // Allow the script to keep running even though we have set a short WireHttp timeout ignore_user_abort(true); // The "create variations" task if($input->post('task') === 'create-variations') { $page_id = (int) $input->post('page'); $p = $event->wire()->pages->get($page_id); // Create an image variation for each image foreach($p->images as $image) { $image->size(1200, 1200); } return true; } return false; }); Then in the Pages::saveReady hook we use WireHttp to load that URL and post parameters that define what task to run and anything else needed for the task (in this case the ID of the page that has been saved). $pages->addHookAfter('saveReady', function(HookEvent $event) { /** @var Page $page */ $page = $event->arguments(0); // When a gallery page is saved if($page->template == 'gallery') { // Load the /run-task/ URL using WireHttp $http = new WireHttp(); // Set a short timeout so we don't have to wait until the script finishes // Timeout values shorter than 1 second can be tried once a core issue is fixed // https://github.com/processwire/processwire-issues/issues/1773 $http->setTimeout(1); $url = $event->wire()->config->urls->httpRoot . 'run-task/'; $data = [ 'key' => 'cTdPMBQ7x8b7', 'task' => 'create-variations', 'page' => $page->id, ]; $http->post($url, $data, ['use' => 'curl']); } }); By doing it this way the task runs in a separate request and the website editor doesn't have to wait for it to finish before they can continue working in the PW admin.1 point
-
Thanks for sharing! As always, your contribution to ProcessWire and its community rocks!1 point
-
Two great news!! 1) The module directory now reads module version numbers from package.json files!! Now when using automated workflows like shown above your module's version in the modules directory will automatically be in sync with your module ? 2) Microsoft has just released the github actions extension for VSCode that helps developing and debugging github actions directly from within your IDE!! https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-github-actions1 point
-
I’m actually offended that it left out the one key attribute: “…, and good looking.”1 point
-
how friendly is the processwire community?1 point
-
Just a note, in case you haven't seen them, there are 5 demos currently ?. The READMEs explain it all. Thanks.1 point
-
No issue with "tempalte" but if if ever remember how to write "width" I'm sure I'll pokevolve into a 10x engineer haha.1 point
-
Just found another nice tool for debugging rest apis: https://insomnia.rest/1 point