Jump to content

flydev

Members
  • Posts

    1,327
  • Joined

  • Last visited

  • Days Won

    47

Posts posted by flydev

  1. Its copied on the bottom because its an example of a feature not finished on another (not really) WIP module.

    it does what you are talking about. Copy image from another field, or from a screenshot, it doesnt matter, I understood you was talking about « clipboard ».

    Quote

    Its copied on the bottom because its an example ..

    The specific reason is as you are limited on mimetypes when working with the clipboard write api, in the example above it render the blob in a canvas, on différent format, including webp.

    Voila 🙂 

    • Like 1
  2. Something like that ? I remember i had started to implement the feature in the not finished module editorjs. I can put my hand on it if you want, it shouldn't be missing lot of work as the upload between the two inputfields is still working..

    Click "copy" button on the first pasge, CTRL/COMMAND+V on the second.

     

     

    Edit: I must admit that this feature could be handy in the core image things.

    • Like 1
  3. Glad to hear it, thanks for the kind of words., do not hesitate to try Duplicator integration in wire-cli.

    To get back to the topic, understood, then you should be able to get started quickly, With both web3 you will get users/guest wallet connected. To interact with Ethereum and smart-contracts, the easier way is to use one of the cleanest API made by Alchemy through their alchemy-sdk. You will be able with something like ten lines of code to get the tokens (fungible or not) from the contract(s) of your choices and then send ajax request to your scripts/templates to set something in the user session and let user view the hiddens pages and/or medias.

    Do you use a "vanilla" JS/PHP frontend or are you on React, Svelte or something?

    • Like 2
  4. Hi,

    I "don't get what you have in mind" when you say "managed by" but things are pretty easy. Just associate public wallet address(es) of an user in the system user template by adding a new field to it. You will need a custom module and/or some hooks to interact with ProcessWire's session, brainstorming needed there before going further.

    The workflow then could be:

    1. the user land on the site
    2. he process to log in by connecting his wallet address
    3. if this address is known then proceed to log in after the user sign the transaction
    4. if there are no account associated with this address, create the account with user approbation (signing transaction)

    The account creation will be only made after the user selected hs wallet, and signed the transaction you sent to it.

    Then I highly suggest you to use a battle tested solution to interact with wallets as there are multiple way of interacting with them, knowing that all wallet do not use the same method. For example you will find different process between CoinbaseWallet, TrustWallet using WalletConnect and Metamask/Phantom, not to mention the various blockchains implementation, eg. Ripple.

    So, about the lib to use, just use Web3Modal  made by WalletConnect or Web3-Onboard made by Blocknative.

    Another solution which is good to know it exist, I used it in january when I built a desktop app wallet (this one is not the cheapest you will find and it's more focused for established companies), is WaaS (wallet as a service) by cryptoapis.io and using HD wallets (xPub, yPub, zPub), TSS and distributed key. More complex things.

    Feel free to ask more infos, as I had planned to write a module for all this mess and it might be a good starting point while interacting with some users starting with Web3 and ProcessWire 👍

    ---

    Edit:
    About the connector/solution you posted above, it look legit, but I think we never heard about them here in the forum, it seem to be an indian company. You might want to contact them directly from the official website, note that the ProcessWire connector IS NOT listed there.

    The SHA fingerprints of the GoDaddy certificate on both urls are the same.

     

    • Like 2
  5. Hello, welcome.

    A template file is required only if you want  to navigate to or view a page associated with this template on the frontend side.

    So in your case, you need to create a file partner_3.ph(empty or not) in site/templates.

    What you mean by « no access to theme files » ?
     

  6. It look like a namespace issue. To debug it, what I would do in first instance, is to make backup of databases of the fresh installs which is working, and then the others. 

    After that, I would compare dbs with a good tools like BeyondCompare. 

    In second instance, I would write a script to extract all namespace declaration and use directives to see if there is something to spot.

  7. This is a bit hackish and add only obscurity. There is a better way that not everyone are aware of to achieve what OP ask if it's ok to let users log in into the backend, I didn't followed all the topic previously.

    Keep in mind that you can override parts of the AdminTheme.  To give you an example, let's assuming you are on a default setup with AdminThemeUikit, then follow theses steps:

    1. create a new directory AdminThemeUikit in site/templates
    2. create a file called _restricted-masthead.php and paste the code you will find at the end of this post
    3. copy the file _main.php from /wire/modules/AdminTheme/AdminThemeUikit/_main.php into /site/templates/AdminThemeUikit
    4. adjust the behavior of the admin theme as you want in _main.php (example below, just replace the full code)

     

    • Code of _main.php 👇
    Spoiler
    <?php namespace ProcessWire;
    
    use function Composer\Autoload\includeFile;
    
    /**
     * _main.php: Main markup template file for AdminThemeUikit
     *
     * FileCompiler=0
     *
     */
    
    if(!defined("PROCESSWIRE")) die();
    
    /** @var Config $config */
    /** @var AdminThemeUikit $adminTheme */
    /** @var User $user */
    /** @var Modules $modules */
    /** @var Notices $notices */
    /** @var Page $page */
    /** @var Process $process */
    /** @var Sanitizer $sanitizer */
    /** @var WireInput $input */
    /** @var Paths $urls */
    /** @var string $layout */
    /** @var Process $process */
    
    $adminTheme->renderExtraMarkup('x'); // forces it to cache
    if(!isset($content)) $content = '';
    
    
    /// restricted user
    //  if user has role `restricted`, then get the page's url of the page id 1105
    //  and redirect the user to this page once logged (page 1105 is just an example). 
    $restricted = $user->hasRole('restricted'); 
    if ($restricted) {
      $hisPageUrl = $pages->get(1105)->editUrl;
      $id = $input->get('id');
      if((int)$id !== 1105)
        $session->redirect($hisPageUrl);
    }
    // /restricted user
    
    
    ?><!DOCTYPE html>
    <html class="pw" lang="<?php echo $adminTheme->_('en');
    	/* this intentionally on a separate line */ ?>">
    <head>
    	<?php 
    	$adminTheme->includeFile('_head.php', array('layout' => $layout));
    	echo $adminTheme->renderExtraMarkup('head'); 
    	?>
    </head>
    <body class='<?php echo $adminTheme->getBodyClass(); ?>'>
    
    <?php 
      if (!$restricted) { // IF NOT in restricted area, show default layout
        if($layout == 'sidenav') {
          $adminTheme->includeFile('_sidenav-masthead.php');
        } else if($layout == 'sidenav-tree' || $layout == 'sidenav-tree-alt') {
          // masthead not rendered in this frame
          echo $adminTheme->renderNotices($notices);
          echo "<div class='uk-margin-small'></div>";
          
        } else if($layout == 'modal') {
          // no masthead
          echo $adminTheme->renderNotices($notices);
          
        } else {
          $adminTheme->includeFile('_masthead.php');
        }
      }
      // IF in restricted area, show the restricted layout
      else {
        include_once($config->paths->templates . 'AdminThemeUikit/_restricted-masthead.php');
      }
      	
    	$headline = $adminTheme->getHeadline();
    	$headlinePos = strpos($content, "$headline</h1>");
    	if($headlinePos && $headlinePos > 500) $headline = '';
    	
    	$adminTheme->includeFile('_content.php', array(
    		'headline' => $headline, 
    		'content' => &$content, 
    		'layout' => $layout
    	));
    	
      // Show footer only IF NOT restricted
      if (!$restricted) {
        if(!$adminTheme->isModal) {
          $adminTheme->includeFile('_footer.php');
          if($adminTheme->isLoggedIn && strpos($layout, 'sidenav') !== 0) {
            $adminTheme->includeFile('_offcanvas.php');
          }
        }
      }
    
    	echo $adminTheme->renderExtraMarkup('body');
    	$adminTheme->includeFile('_body-scripts.php', array('layout' => $layout));
    ?>
    	
    </body>
    </html><?php

     

     

    • Code of _restricted-masthead.php 👇
    Spoiler
    <?php namespace ProcessWire;
    
    if(!defined("PROCESSWIRE")) die();
    
    /** @var AdminThemeUikit $adminTheme */
    /** @var User $user */
    /** @var array $extras */
    /** @var Paths $urls */
    /** @var Config $config */
    /** @var Notices $notices */
    
    $logoOptions = array('height' => '40px');
    ?>
    <div id='pw-mastheads'>
    	<header id='pw-masthead-mobile' class='pw-masthead uk-hidden uk-background-muted'>
    		<div class='pw-container uk-container uk-container-expand<?php if(!$adminTheme->isLoggedIn) echo ' uk-text-center'; ?>'>
    				<a href='<?php echo $adminTheme->isLoggedIn ? $config->urls->admin : $config->urls->root; ?>' class='pw-logo-link'>
    					<?php echo $adminTheme->getLogo($logoOptions); ?>
    				</a>
    		</div>	
    	</header>
    	<header id='pw-masthead' class='pw-masthead uk-background-muted' data-pw-height='80'> <?php /* data-pw-height='73' */ ?>
    		<div class='pw-container uk-container uk-container-expand'>
    			<nav class='uk-navbar uk-navbar-container uk-navbar-transparent' uk-navbar>
    				<div class='uk-navbar-left'>
    					<a class="pw-logo-link uk-logo uk-margin-right" href='<?php echo $adminTheme->isLoggedIn ? $config->urls->admin : $config->urls->root; ?>'>
    						<?php echo $adminTheme->getLogo($logoOptions); ?>
    					</a>
    				</div>
    				<?php if($adminTheme->isLoggedIn): ?>
            <div class="uk-navbar-center uk-text-bold uk-text-danger">
              <h2>RESTRICTED AREA</h2>
            </div>
    				<div class="uk-navbar-right">
    					<ul class='uk-navbar-nav uk-margin-right pw-user-nav'>
    						<li>
    							<a id="tools-toggle" class="pw-dropdown-toggle" href="<?php echo $urls->admin; ?>profile/">
    								<?php echo $adminTheme->renderUserNavLabel(); ?>
    							</a>
    							<ul class="pw-dropdown-menu" data-my="left top" data-at="left bottom" style="display: none;">
    								<?php if($config->debug && $adminTheme->isSuperuser && strpos($adminTheme->layout, 'sidenav') === false): ?>
    								<li>	
    									<a href='#' onclick="$('#debug_toggle').click(); return false;">
    										<?php echo $adminTheme->renderNavIcon('bug') . __('Debug', __FILE__); ?>
    									</a>
    								</li>
    								<?php  endif; ?>
    								<?php echo $adminTheme->renderUserNavItems(); ?>
    							</ul>
    						</li>
    					</ul>	
    				</div>
    				<?php endif; // loggedin ?>
    			</nav>
    		</div>
    	</header>
    	<?php 
    	if(strpos($adminTheme->layout, 'sidenav') === false) {
    		echo $adminTheme->renderNotices($notices);
    		echo $adminTheme->renderExtraMarkup('masthead');
    	}
    	?>
    </div>	

     

     

    • Result

     - https://streamable.com/jg2l0p

     

    More informations there: 

    https://github.com/processwire/processwire/blob/dev/wire/modules/AdminTheme/AdminThemeUikit/README.md

     

     

    Enjoy ✌️

    • Like 2
  8. 47 minutes ago, Roadwolf said:

     I am a little confused why posts I am adding seem to be finding their way into the correct categories with the correct settings, but aren't showing up in the live main page of the blog unless you specifically seek out an article.   Does the main page need articles specifically added to the feed?

    Could you give us a bit more of details of how your structure / pages tree look like ? Also, which "output strategy" did you choose ?

    Basically, the main page - which by default is called `home` with a template also called `home` - doesn't require something special. You have full control of what and how things are displayed.

    If for example, your tree look like the following: 

    Page Title [template name]
    --------------------------
    |- Home [home]
    |--- Blog Parent [blog]
    |------ Post1 [blogpost]
    |------ Post2 [blogpost]

    To show blog posts in the frontend page Home [home] (home.php) you want to write something like:

    <?php namespace ProcessWire;
    
    $blogposts = $pages->find("template=blogpost, limit=10"); // this is a selector, $blogposts will contain the two page objetcs Post1 and Post2 
    
    // loop through all blogposts contained in variable $blogposts
    foreach($blogposts as $post) {
      echo "<h2>$post->title</h2";            // echo title field
      $excerpt = substr($post->body, 0, 150); // simple excerpt to illustrate, 150 chars from body field
      echo "<p>$excerpt</p>"; 
    }

    Hope you get the idea.

    • Like 1
  9. You can find here the release of wire-cli, successor to wire shell, a powerful command-line interface (CLI) tool designed specifically for ProcessWire developers. Optimize your workflow, automate repetitive tasks, and manage your ProcessWire projects with ease.

    Wire-cli leverages the Symfony Console Component to provide a robust CLI experience, offering a wide range of features and commands to enhance your development process. From creating new projects and managing fields, templates, roles, and users, to performing database backups and serving your ProcessWire projects with a built-in web-server.

    Still in development, there might be some glitch, I will continuously improve and expand its functionality based on the feedback and needs of the ProcessWire community. Also mentioning that we will be probably working towards merging the features of wire-cli and rockshell to provide a unified CLI solution for ProcessWire.

    To get started with wire-cli, check out the GitHub repository or simply install it now from your terminal using Composer:

    composer global require wirecli/wire-cli

    Contributions are welcome. If you encounter any issues or have suggestions for improvements, please submit an issue, a pull request or post it here.

     

    horizontal-alpha-png24.png.f35e4e3966778f9e34531a1dc57630fe.png

    • Like 17
    • Thanks 2
  10. Hello,

    What @cwsoft said. 

    Adding, for example, if you need using it in your own namespace, you can connect ProcessWire like this:

    <?php namespace Foo\App;
    
    use Foo\BarClass;
    use ProcessWire\Page;
    
    class PwConnector {
    
      public function init() {
        $this->bootstrapProcessWire();
      }
      
      protected function bootstrapProcessWire() {
        $pw_dir = '/var/lib/www/pw'; // example, processwire is installed here
        if (!function_exists('\ProcessWire\wire')) include($pw_dir . '/index.php');
        echo \ProcessWire\wire('pages')->get('/')->title; // echo home title
      }
      
      // ...
    }

     

      

    33 minutes ago, cwsoft said:

    But it wouldn‘t provide lot of features to access non PW user credential infos like login data of your App outside PW etc.

    He will still benefit an easy API to use to access them by using the $database object, if stored externally.

    • Like 2
  11. Hello @Roadwolf welcome here !

    I will let other members giving you a better written introduction and greeting and I will most try to give some answers and thread links to confirm you ended on the right place. Your 18 years old website/blog deserve a good software to run on.

    Recently, a member posted about his website thats was not working (spoiler: we are talking about the backend side) where it turns out to be more of a "problem" with the hosting provider configuration. Just speaking about it, first because ProcessWire get updated every friday (this can be tracked on github and in the announcement section here in the forum), it let you being confident on how robust and secure the software is, secondly, we almost never seen an upgrade being problematic, even going from major version 2 to 3, assuming you have a small technical habits to follow basics steps.

    About multisite, I think yes, but I have never personally tried, so others will answer to it. 

    1 hour ago, Roadwolf said:

    I do tend to enjoy doing things the 'hard way' or old school way when it comes to scripting and customizing things.

    Then you will love it 💯

    1 hour ago, Roadwolf said:

    But I also enjoy and appreciate a helpful and friendly community, to help me learn and guide me when I am tackling a new project such as a new CMS.  And I hope to find that here?

    Even GPT tends to throw a lot of confettis on this community, if you ask her, you will love it 💯x 2 😁

    1 hour ago, Roadwolf said:

    I wonder if there is any sort of integration to turn photos uploaded into NFT's automatically with this CMS?

    Interesting. The answer is no, at least there is no built-in solution, and from what I know, there is no module available for that. But it can be achieved really easily, thanks to ProcessWire freedom. The day you start to put your hands on it, do not hesitate to ping me, I have personally some experiences with NFTs, smart-contract and all this mess so I could give some help in this regard.

    Yo will find a lot of resources here on the forum,  well explained, and do not be afraid if you see some tens years old junks of code, they will almost all still work 😄 , give a read to the nice blog posts, register to weekly.pw to receive the best of it each weekend for nice read while taking coffee.

    Enjoy your PW journey 🙂

     

    • Like 7
  12. 1 hour ago, ngrmm said:

    An image field on the profile page would be editable with the help of InputfieldFrontendFile

    I was going to suggest it. Unfortunately, I don't own it I think as I have the very first version. I will take a look. But you could ask Ryan directly.

    Playing with InputfieldImage and InputfieldFile from frontend is not trivial, as is. If you do not get an answer, I will come back to this thread once I get my hand on the module source-code.

    Edit:

    Just in case, you can also implement a custom form for files (https://gist.github.com/jacmaes/6691946) and play with a bit of JS to render things dynamic. And to generate random links, you can take a look at this (I am still using it, even if the module is born almost ten years ago: https://github.com/plauclair/FieldGenerator)

    • Like 1
  13. 59 minutes ago, Inxentas said:

    Heyyyy https://www.orchardheightsdental.com/ is back up! I dunno what you did, but it worked! Nice! 😁

    But not the backend which give a 500 error.

    Anyway, you just have to throw a lot of confettis on @ryan . Read below. This piece of software look solid, love this quote so much 💙

     

    On 6/7/2023 at 3:49 PM, ryan said:

     ...you are running a much older version of ProcessWire... I can tell that you are running a pretty old version because it is missing the JS files for AdminThemeUikit, which was added more than 6 years ago. The good news is that the front-end of your site seems to be working.

     

    • Like 3
  14. Hi,

    `$this->addHook()` give you the ability to define a custom method that can be available in the class object given as a parameter.

     $this->addHook('Page::summarize',     $this,            'summarize');
                       |       |              |                   |- (name of the method defined in the current object (module, class..)
                       |       |              | 
                       |       |              |- current object where the method is defined (module, class)
                       |       | 
                       |       |- the name is mandatory, 
                       |          you will call the method given as third param from the Page $page object ($page->summarize()).
                       |
    				   |- the object where the new method will be added to

     

    In the example of the `summarize()` method you are talking about, it expect a method `summarize()` to be defined in an autoload module. But you are not required to write a module just to define a new method to an existing class. You can write it outside a class, for example, in the file `init.php` by writing the following:

    $this->addHook('Page::summarize', function ($event) {
     // the $event->object represents the object hooked (Page)
     $page = $event->object;
     // first argument is the optional max length
     $maxlen = $event->arguments(0);
     // if no $maxlen was present, we'll use a default of 200
     if(!$maxlen) $maxlen = 200;
     // use sanitizer truncate method to create a summary
     $summary = $this->sanitizer->truncate($page->body, $maxlen);
     // populate $summary to $event->return, the return value
     $event->return = $summary;
    });
    
    // or by defining the function... 
    
    function summarize_2($event) {
      // the $event->object represents the object hooked (Page)
      $page = $event->object;
      // first argument is the optional max length
      $maxlen = $event->arguments(0);
      // if no $maxlen was present, we'll use a default of 200
      if(!$maxlen) $maxlen = 200;
      // use sanitizer truncate method to create a summary
      $summary = wire()->sanitizer->truncate($page->body, $maxlen);
      // populate $summary to $event->return, the return value
      $event->return = $summary;
     };
    
    // ... and giving the name of the function to the hook.
    // note the `null` parameter used to tell the hook we are not using it from a class object
    $this->addHook('Page::summarize_2', null, 'summarize_2');

    You will be using a hook where `after` or `before` doesn't matter, to define a new method `summarize()` to the existing class `Page`.

    So in your template, eg. `home.php` or `basic-page.php`, you can then call both methods from the `$page` api variable.

    <?php namespace ProcessWire;
    
    // Template home.php
    
    // if the `body` field content is: "The body field of this page summarized in less than 200 characters, or it will be truncated."
    // calls of the new defined methods `summarize()` and `summarize_2()` will print the content of the `body` field.
    
    echo $page->summarize();
    
    echo $page->summarize_2();

     

    If you want to test it from a module, then is quite simple (note we replace the `null` param by `$this` to tell the hook we are using it from the current object class (themodule): 

    class ExampleSummarize extends WireData implements Module {
      public static function getModuleInfo() {
        return [
          'title' => 'Example Summarize module',
          'version' => 1,
          'summary' => 'Add a new method `summarize()` to page object.',
          'autoload' => true,
        ];
      }
    	
      function summarize($event) {
      // the $event->object represents the object hooked (Page)
      $page = $event->object;
      // first argument is the optional max length
      $maxlen = $event->arguments(0);
      // if no $maxlen was present, we'll use a default of 200
      if(!$maxlen) $maxlen = 200;
      // use sanitizer truncate method to create a summary
      $summary = wire()->sanitizer->truncate($page->body, $maxlen);
      // populate $summary to $event->return, the return value
      $event->return = $summary;
     };
    
      public function init() {
        $this->addHook('Page::summarize', $this, 'summarize');
      }
    }

    If you write this code in a file `ExampleSummarize.module` and from the backend you refresh modules and install this module, the method `summarize()` will be available by calling `$page->summarize()` from where you want.

     

    You can also find more informations and lot of details there:

    https://processwire.com/docs/modules/hooks/

     

     

     

    • Like 7
    • Thanks 1
  15. Hi, 

    Step #1

    💡👉  The first step IS to make a backup of everything. 


    2. Connect to your host, and make a backup of the database, with PHPMyAdmin or any  tool available on the hosting provider. You will find it in their documentation.

    3. Download all the files of your website. By FTP or eventualy making a ZIP archive from the administration page of the hosting provider.

    4. Triple check your backup

    Then if you follow the steps on the answer of the question of @Inxentas which he just linked above it should work. 

    If you are worried, and as Ryan said, your frontend is working, so I suggest you giving a try on your own computer with a simple oneclick webserver. There is no dev steps involded.

    Please, again, make a backup of everything before doing any upgrade and do not hesitate to ask further help here.
     

     

  16. 39 minutes ago, wbmnfktr said:

    I have seen this or maybe a very similar warning a few times - not with DDEV as I only use project abbreviations and not fully qualified domain names there.

    So your project would be running as something like brk.ddev.site here.
    Chrome is fine with that.

    Possible solutions:

    • don't use full domain names
    • use abbreviations instead
    • write it domain-tld instead

     

    And always remember the ddev.site part is a fully qualified domain thats registered and everything.
    So technically yourproject.ddev.site is/could be a real subdomain and due to some security features Chrome tries to verify that this subdomain is secure and everything.

    ddev.png.18a7c3c20b4da8f66c13a984a581e57a.png

    This 👍 

    « Just » make an offer on ddev.site and put the certificat on your setup 😁

    Another solution is to make your own self signed certificate and add it to your OS certificates authority in order to trust it.

    • Haha 2
×
×
  • Create New...