Jump to content

FieldtypeQRCode


Recommended Posts

Posted (edited)

(once again I was surprised to see a work of mine pop up in the newsletter, this time without even listing the module on PW modules website ūüėÖ. Thx @teppo !)

FieldtypeQRCode

Github: https://github.com/romaincazier/FieldtypeQRCode
Modules directory: https://processwire.com/modules/fieldtype-qrcode/

A simple fieldtype generating a QR Code from the public URL of the page, and more.

Using the PHP library QR Code Generator by Kazuhiko Arase.

screenshot

Options

In the field’s Details tab you can change between .gif or .svg formats. If you select .svg you will have the option to directly output the markup instead of a base64 image. SVG is the default.

You can also change what is used to generate the QR code and even have several sources. The accepted sources (separated by a comma) are: httpUrl, editUrl, or the name of any text/URL/file/image field.

If LanguageSupport is installed the compatible sources (httpUrl, text field, ...) will return as many QR codes as there are languages. Note however that when outputting on the front-end, only the languages visible to the user will be generated.

Formatting

Unformatted value

When using $page->getUnformatted("qrcode_field") it returns an array with the following structure:

[
	[
		"label" => string,  // label used in the admin
		"qr" => string,     // the qrcode image
		"source" => string, // the source, as defined in the configuration
		"text" => string    // and the text used to generate the qrcode
	],
	...
]

Formatted value

The formatted value is an <img>/<svg> (or several right next to each other). There is no other markup.

Should you need the same markup as in the admin you could use:

$field = $fields->get("qrcode_field");
$field->type->markupValue($page, $field, $page->getUnformatted("qrcode_field"));

But it’s a bit cumbersome, plus you need to import the FieldtypeQRCode's css/js. Best is to make your own markup using the unformatted value.

Static QR code generator

You can call FieldtypeQRCode::generateQRCode to generate any QR code you want. Its arguments are:

string $text
bool   $svg    Generate the QR code as svg instead of gif ? (default=true)
bool   $markup If svg, output its markup instead of a base64 ? (default=false)

Hooks

Please have a look at the source code for more details about the hookable functions.

Examples

$wire->addHookAfter("FieldtypeQRCode::getQRText", function($event) {
	$page = $event->arguments("page");
	$event->return = $page->title;
	// or could be: $event->return = "Your custom text";
})
$wire->addHookAfter("FieldtypeQRCode::generateQRCodes", function($event) {
	$qrcodes = $event->return;
	// keep everything except the QR codes generated from editUrl
	foreach($qrcodes as $key => &$qrcode) {
		if($qrcode["source"] === "editUrl") {
			unset($qrcodes[$key]);
		}
	}
	unset($qrcode);
	$event->return = $qrcodes;
})
Edited by monollonom
  • Like 9
  • Thanks 1
Link to comment
Share on other sites

5 hours ago, monollonom said:

this time without even listing the module on PW modules website

Don't mess with @teppo. He sees and knows almost everything and therefore we love him so much (but don't tell him).

Thank you as well for your module. This might and will be a great addition for a lot of us.

  • Like 2
  • Haha 3
Link to comment
Share on other sites

I made a small update where you can now output the QR Code on the front-end by calling the field directly (instead of rendering the inputfield) and I added the option to output the image in either .svg or .gif (if .svg, you'll have the additional ability to output the markup directly, instead of a base64).

  • Like 7
  • Thanks 1
Link to comment
Share on other sites

  • 3 weeks later...
  • 4 months later...

Hi @monollonom - thanks for a very useful module.

One thing I noticed is that render() is called twice. I think this is easily fixed by replacing:

return $this->render();

with:

return $value;

in the sanitizeValue() method.

You can also remove the other two lines from that method also because I don't think you plan is to modify anything in that method.

Thanks!

  • Like 2
Link to comment
Share on other sites

Hi @adrian,

Glad the module is of help and thank you for the feedback!

I applied your suggested changes and at first got an empty output on the front-end. However, taking some cues from @Robin S's FieldtypeRuntimeOnly, I managed to apply the necessary changes for it to work properly.

And as a nice side effect the ___getQRText hook now has access to the current $page!

Thanks again.

  • Like 1
Link to comment
Share on other sites

21 minutes ago, monollonom said:

I applied your suggested changes and at first got an empty output on the front-end

Interesting. I was making use of the ___getQRText so I never an empty output - I expect that was why. 

Thanks for the updates, especially the access to the current page - much nicer than my hack to get it.

Link to comment
Share on other sites

Unfortunately, this new version is still calling the new renderQRCode() method twice. 

I changed both the ___markupValue() and ___wakeupValue() methods to just return $value and everything seems good again. Keep in mind that I haven't tested the output in all scenarios, but it is working in the admin edit process. Probably a good place would be to check in a Lister view to make sure ___markupValue() is working correctly still.

Actually, it looks like @Robin S's RuntimeOnly is calling its renderMarkup() twice so I think it needs some attention as well.

  • Thanks 1
Link to comment
Share on other sites

Okay so I boiled it down to this:

Apparently there's no need to have markupValue() return anything else other than $value as it most likely calls wakeupValue() in any case. Also I went ahead and removed the part hooking into the render() function of the InputfieldMarkup. This removed the double call on the back-end while keeping the front-end call working.

Thanks again, I'm pushing the update right now!

  • Like 3
Link to comment
Share on other sites

3 minutes ago, monollonom said:

Also I went ahead and removed the part hooking into the render() function of the InputfieldMarkup.

I was wondering about the need for that - glad that could also be removed.

Everything looks good here now - thanks again!

  • Thanks 1
Link to comment
Share on other sites

1 hour ago, adrian said:

Actually, it looks like @Robin S's RuntimeOnly is calling its renderMarkup() twice so I think it needs some attention as well.

@adrian, could you please open a GitHub issue or raise this in the RuntimeOnly support thread? I'd like to confirm a few details but don't want to take this thread off-topic.

  • Like 1
Link to comment
Share on other sites

I just published a new release of the Fieldtype and updated the original post with a copy of the README.

I think it's pretty complete at this point: you can output several QR codes by specifying the sources in the field's config (limited to httpUrl, editUrl and PageFiles/PageImages fields), it supports multi-languages by outputting as many QR codes for httpUrl as there are languages (only those visible to the user when output in the front-end), there is now a static function to generate any QR code you want and there are several functions you can hook at to adjust according to your needs.

Let me know if you notice anything strange or a bug!

  • Like 3
Link to comment
Share on other sites

Thanks @monollonom for the new version. One thing I'd like to see is removal of the language dropdown unless "Languages Support - Page Names" is installed. In my case I am using ML, but I don't have language specific URLs, so that dropdown is just confusing.

What do you think?

Thanks.

Link to comment
Share on other sites

This should take care of the language change I am suggesting:

                if($this->wire('modules')->isInstalled('LanguageSupportPageNames')) {
                    $out .= $this->renderSelectOptions($options);
                }

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

48 minutes ago, adrian said:

Something else to be aware of - getting errors when using this with Ryan's TOTP module.

https://github.com/ryancramerdesign/TfaTotp/issues/3

Is this still the case ? I changed the way I import the library by putting it in the __construct rather than outside the class. Also it's weird because in Ryan's case its class is namespaced "Processwire\TfaTotp" so there shouldn't be conflicts ? Or maybe I should use a namespace as well ?

48 minutes ago, adrian said:

This should take care of the language change I am suggesting:
 

if($this->wire('modules')->isInstalled('LanguageSupportPageNames')) {
    $out .= $this->renderSelectOptions($options);
}

Thanks for your suggestion. I don't see any issue to adding this, I'll let you know once it's done.

Maybe it's something to keep in mind to allow to say which language to output from the "source" config input, something like "httpUrl.default" (opening the way to other ways to narrow down what to output for files/images but I'm already getting too far ahead...)

  • Like 1
Link to comment
Share on other sites

2 hours ago, adrian said:

Something else to be aware of - getting errors when using this with Ryan's TOTP module.

https://github.com/ryancramerdesign/TfaTotp/issues/3

Re: this, it seems to be because constants declared using define() do not respect namespace unless explicitely specified. One solution though seems to be to replace define() by const declarations. I'll try to do that tomorrow (also what you suggested is done but I want to also fix this first).

  • Like 2
Link to comment
Share on other sites

Thanks for sorting out the conflicts.

Actually thinking about the ML stuff - maybe my proposed solution isn't the best - sites may still be set up with /en/ /es/ etc as a way of having different language URLs for each page without needing to have LanguageSupportPageNames installed. Maybe you could just add an option to enable or disable the select dropdown instead?

Link to comment
Share on other sites

8 hours ago, adrian said:

Thanks for sorting out the conflicts.

Actually thinking about the ML stuff - maybe my proposed solution isn't the best - sites may still be set up with /en/ /es/ etc as a way of having different language URLs for each page without needing to have LanguageSupportPageNames installed. Maybe you could just add an option to enable or disable the select dropdown instead?

Do you mean like relying on urlSegment instead ?

Implementing your feature I actually came across a situation where it would output the same URL twice because the page name of the root page wasn‚Äôt defined in the non-default language. So what I did is to add a check to make sure to not output the same QR code twice (plus the default language will just be labeled ‚ÄúURL‚ÄĚ).

Does it sound like it would help in your situation ? Even if not checking for LanguageSupportPageNames.

  • Like 2
Link to comment
Share on other sites

I went ahead and pushed the latest release.

I tested uninstalling LanguageSupportPageNames while still having LanguageSupport and it works as expected, outputting only the default language URL.

I also namespaced the QR code php generator and it should help solve your issue with TOTP.

Let me know if you notice anything else @adrian and otherwise thanks for your feedbacks!

  • Like 3
Link to comment
Share on other sites

I just published another update.

Following a pull request / suggestion from a friend I added support for any text and URL field. Multi-languages support is still there and the field will output as many (non-empty) texts as there are languages. I haven't tested with the textarea field but I assume it will generate the QR code from the raw markup, before any textformatter is applied. I believe this won't be a common use-case, but if need be you can always use hooks to adjust or generate your own QR code.

I also fixed an issue where the template-contextual settings weren't applied.

Please let me know if you run into any issue.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Similar Content

    • By monollonom
      PageMjmlToHtml
      Github: https://github.com/romaincazier/PageMjmlToHtml
      Modules directory: https://processwire.com/modules/page-mjml-to-html/
      A module allowing you to write your Processwire template using MJML and get a converted HTML output using MJML API.
      This is considered to be in alpha and as such needs some testing before being used in production!

      About
      Created by Mailjet, MJML is a markup language making it a breeze to create newsletters displayed consistently across all email clients.
      Write your template using MJML combined with Processwire’s API and this module will automatically convert your code into a working newsletter thanks to their free-to-use Rest API.
      Prerequisite
      For this module to work you will need to get an API key and paste it in the module’s configuration.
      Usage
      Once your credentials are validated, select the template(s) in which you’re using the MJML syntax, save and go visualize your page(s) to see if everything’s good. You will either get error/warning messages or your email properly formatted and ready-to-go.
      From there you can copy/paste the raw generated code in an external mailing service or distribute your newsletter using ProMailer.
      Features
      The MJML output is cached to avoid repetitive API calls Not cached if there are errors/warnings Cleared if the page is saved Cleared if the template file has been modified A simple (dumb?) code viewer highlights lines with errors/warnings A button is added to quickly copy the raw code of the generated newsletter Not added if the page is rendered outside of a PageView Only visible to users with the page‚Äôs edit permission A shortcut is also added under ‚ÄúView‚ÄĚ in the edit page to open the raw code in a new tab Multi-languages support
      Notes
      The code viewer is only shown to superusers. If there’s an error the page will display:
      Only its title for guests Its title and a message inviting to contact the administrator for editors If you are using the markup regions output strategy, it might be best to not append files to preserve your MJML markup before calling the MJML API. This option is available in the module’s settings.
    • By Marco Ro
      Hi guys!
      I'm a bit anxious because this is the first module I present! (beta modulo) But I will finally be able to share something with the community too! :)
      This is a BETA version of the PayPal payment system called: PayPal Commerce Platform.
      It is an advanced system (Business Pro account is needed) that brings various benefits in terms of fees and above all integrates direct payment with credit/debit cards. 
      The module integrates with Padloper 0.0.2, which is the current installation I'm using.
      This system integrates the classic PayPal buy button, the alternative or local payment method and the new payment system: credit/debit cards that doesn't go through the PayPal account. It is a Stripe-style payment, it connects directly with the bank and integrates 3D security validation.
      I say that it is a BETA because this module currently only works with Sandbox account, to put it live you need to change API url manually (manually for the moment).
      Because this module is not ready for live:
      I would like to have your opinion on how I built the module (is the first one I do). I don't want to share something that is not fish but I need a comparison with someone more experienced than me, for be sure that this is the best way to code the module.
      If you want to try this I created a git, you will find all the instructions for installation and correct operation. (Git has a MIT licensed)
      https://github.com/MarcooRo/processwire-PayPal-Commerce-Platform I hope I did something that you guys can like :)
    • By Sebi
      AppApiFile adds the /file endpoint to the AppApi routes definition. Makes it possible to query files via the api. 
      This module relies on the base module AppApi, which must be installed before AppApiFile can do its work.
      Features
      You can access all files that are uploaded at any ProcessWire page. Call api/file/route/in/pagetree?file=test.jpg to access a page via its route in the page tree. Alternatively you can call api/file/4242?file=test.jpg (e.g.,) to access a page by its id. The module will make sure that the page is accessible by the active user.
      The GET-param "file" defines the basename of the file which you want to get.
      The following GET-params (optional) can be used to manipulate an image:
      width height maxwidth maxheight cropX cropY Use GET-Param format=base64 to receive the file in base64 format.
    • By MarkE
      This fieldtype and inputfield bundle was built for storing measurement values within a field, rendering them in a variety of formats and converting them to other units or otherwise modifying them via the API.
      The API consists of a number of predefined functions, some of which include...
      render() for rendering the measurement object, valueAs() for converting the value to another unit value, convertTo() for converting the whole measurement object to different units, and add() and subtract() for for modifying the stored value by the value (converted as required) in another measurement. In the admin the inputfield includes a checkbox (which can be optionally disabled) for converting values on page save. For an example if a value was typed in as centimeters, the unit was changed to metres, and the page saved with this checkbox selected, said value would be automatically converted so that e.g. 170 cm becomes 1.7 m.

      A simple length field using Fieldtype Measurement and Inputfield Measurement.
      Combination units (e.g. feet and inches) are also supported.
      Please note that this module is 'proof of concept' at the moment - there are limited units available and quite a lot of code tidying to do. More units will be added shortly.
      See the GitHub at https://github.com/MetaTunes/FieldtypeMeasurement for full details and updates.
    • By tcnet
      File Manager for ProcessWire is a module to manager files and folders from the CMS backend. It supports creating, deleting, renaming, packing, unpacking, uploading, downloading and editing of files and folders. The integrated code editor ACE supports highlighting of all common programming languages.
      https://github.com/techcnet/ProcessFileManager

      Warning
      This module is probably the most powerful module. You might destroy your processwire installation if you don't exactly know what you doing. Be careful and use it at your own risk!
      ACE code editor
      This module uses ACE code editor available from: https://github.com/ajaxorg/ace

      Dragscroll
      This module uses the JavaScript dragscroll available from: http://github.com/asvd/dragscroll. Dragscroll adds the ability to drag the table horizontally with the mouse pointer.
      PHP File Manager
      This module uses a modified version of PHP File Manager available from: https://github.com/alexantr/filemanager
       
√ó
√ó
  • Create New...