ryan

Hanna Code

Recommended Posts

Thank you, Robin S.

It's so easy to make CKEditor get worried. Your trick prevents the warning message, so it looks less worrying to me...

Share this post


Link to post
Share on other sites

A other solution to Hannacode in this case yould be working with a Textformatter....

If you in concern of usability you could let your user just put in the mp3 file in CKEEditor and let the Textformatter search for it (href regex for *.mp3*) and replace it with the player. So zero worrying about include audio files.

You could take a look at the Youtube Textformatter from Ryan:
https://github.com/ryancramerdesign/TextformatterVideoEmbed/blob/master/TextformatterVideoEmbed.module

...just as an additional option.

regards mr-fan

Share this post


Link to post
Share on other sites

Thanks mr-fan - that seems to be a nice idea! I for sure will take a nearer look into it - after my actual problems hopefully will be solved... (I've got a similar Hanna Code to display a Video, using the jQuery plugin VideoJS - which mostly works well, but not on some mobile devices, e.g. on WinPhone 8 or iPhone...)

Share this post


Link to post
Share on other sites

Hi all

i've used Hannacode to include a php page with a form. The "action" of this form is to another page that have another php file include. Last php file get post var and print the result. The problem is that when i submit the form 8/10 the new page loading but site freeze. If i reload the page (and re-submit the form) it works. I don't know if it depends to hannacode or processwire.  I have another site on same server written in pure php but i never have this type of problem.

Thank in advance.

 

 

 

Below the result page php code:

Hannacode

<?php
    include (wire('config')->paths->templates.'_form-application-result.php');
?>

_form-application-result.php

<?php
	foreach ($input->post as $k=>$v) {


      if ($v != '' && $k != 'g-recaptcha-response') {
        $session->set($k,trim($v));
  ?>

        <div class="row">
            <div class="col-sm-3"><?= ucwords(str_replace('_',' ',$k)) ?></div>
            <div class="col-sm-9"><?= strtoupper($v) ?></div>
        </div>

  <?
      }

    }

 

Share this post


Link to post
Share on other sites

It's harder to edit files inside Ace editor where you can't get proper debugging, type hinting, autocomplete etc. So what I propose is a way to hook into the module. Then we could:

<?php 
// filtered hook for some specific Hanna code
wire()->addHook('TextformatterHannaCode::getPHP(name="random-post")', function(HookEvent $e) {
  // the arguments specified by the user, inside an associated array
  $args = $e->arguments(0);
  // build markup, 
  // since $vars parameter is an array 
  // we can pass it directly as variables for the template
  $e->return = wireRenderFile('template/file', $vars);
  $e->replace = true;
});

and then inside a php file, you perform your checks, build your markup with given parameters, and return it. Making this function hookable is quite easy, this is enough

<?php 
public function getPHP($name, $code, array $attrs) {}
// would become
public function ___getPHP($name, $code, array $attrs) {}
// just prefixing alone probably woudn't allow filtering hooks though.

 

Share this post


Link to post
Share on other sites
1 hour ago, abdus said:

It's harder to edit files inside Ace editor where you can't get proper debugging, type hinting, autocomplete etc.

Actually AceEditor does support this stuff pretty well - I use it in Tracy's Console and Template Editor panels. Perhaps someone could put together a PR for the Hanna code module to add these?

Share this post


Link to post
Share on other sites
1 hour ago, abdus said:

It's harder to edit files inside Ace editor where you can't get proper debugging, type hinting, autocomplete etc. So what I propose is a way to hook into the module.

I also dislike editing code outside of my IDE. The workaround currently is pretty simple - just set this for all your PHP Hanna codes:

include($config->paths->templates . 'hannas/' . $hanna->name . '.php');

But I'm in favour of anything that would make it even easier.

  • Like 1

Share this post


Link to post
Share on other sites
3 hours ago, adrian said:

Perhaps someone could put together a PR for the Hanna code module to add these?

I made a PR for it.

https://github.com/ryancramerdesign/ProcessHannaCode/pull/19

Changes include:

  • Updating module to ProcessWire namespace. This requires standard library classes be prefixed with \ (PDO -> \PDO etc.)
  • Changing internal references inside ProcessHannaCode for TextFormatterHannaCode to use the module instance in $this->hanna instead.
  • Changing getPHPgetJS, and adding getText method for hooking.

This allows hooking into TextformatterHannaCode::getPHP, TextformatterHannaCode::getJS and TextformatterHannaCode::getText. Inside these hooks you check for the hanna code name, then do as you wish, like so

wire()->addHookBefore('TextformatterHannaCode::getPHP', function (HookEvent $e) {
    if($e->arguments(0) === 'refer') {
        $e->replace = true;
        $args = $e->arguments(2);
        // $e->return = wireRenderFile('refer', $args);
        $e->return = 'rendered template output';
    }
});
 
  • Like 1

Share this post


Link to post
Share on other sites

Hmm, one surprising advantage would be addition of shortcodes like in Wordpress. Modules can require, (install if necessary), then hook into Hanna Code and define their own shortcodes to be used in fields. One example would be

<?php
class EmbedShortcodes extends Wire implements Module
{
    public static function getModuleInfo()
    {
        return [
            'title' => 'Shortcodes',
            'version' => '0.0.1',
            'author' => 'abdus',
            'summary' => 'Adds `embed` shortcode',
            'href' => 'https://abdus.co',
            'autoload' => true, // set to true if module should auto-load at boot
            'requires' => [
                'TextformatterHannaCode',
            ],
            'installs' => ['TextformatterHannaCode'],
        ];
    }

    public function ready() {
        $this->addHook('TextformatterHannaCode::getPHP', $this, 'renderEmbed');
    }

    protected function renderEmbed(HookEvent $e) {
        if($e->arguments(0) === 'embed') {
            $e->replace = true;
            $e->return = '<div>embedded output</div>';
        }
    }
}

This works fine for predefined hanna codes, but, for arbitrary shortcodes, it requires a change in the logic of the module where it fetches available hanna codes from database here

<?php
protected function getReplacement($name, array $attrs, &$consume) {

    $database = $this->wire('database');

    $sql = 'SELECT `id`, `type`, `code` FROM hanna_code WHERE `name`=:name';
    $query = $database->prepare($sql);
    bd($name, 'before');
    $query->bindValue(':name', $name, \PDO::PARAM_STR);
    $query->execute();
    if(!$query->rowCount()) return false;
    // here if it cannot find the hanna code it does nothing.
  
    // rest of the function
}

It should be refactored instead into ___getReplacement(), which allows defining access to hanna codes outside the DB.

Once done, we can just [[embed url=youtube.com/asdfgh]] to embed a video etc.

  • Like 1

Share this post


Link to post
Share on other sites

Just a suggestion but it'd be really useful if there was

 

  1. a Description field available when creating a HannaCode. I like to keep my HC names short and choppy and a description would greatly help users later on establishing what the HC is for or does
  2. a Description column on the HannaCode overview page too pulling in above Description

It would also be great to be able to see a list of pages where HCs are used within RTEs or templates but that (for me) isn't such a biggie.

 

  • Like 2

Share this post


Link to post
Share on other sites

Hi,

I've just installed the Hanna Code module. I wanted to try it out first with something simple - using something like [[title]] to easily insert the current page's title in a textarea.

However, when I try to add a new Hanna Code, if I choose the PHP option, I get a 403 error whenever I hit save.

Could there be a permission I need to change somewhere? Please help!

Thanks,

Margaret

PS. I'm running PW 3.0.62

EDIT: Never mind, it's now working.

I'm not entirely sure how, but I got it to work.

For the benefit of any other newcomers who might experience a similar issue in the future...

First I created a Text/HTML Hanna Code called figurename and just made it output <strong>Boo!</strong>. It let me save it and it worked on my page.

I then edited that code by changing it to PHP - it let me save. I then changed the code to echo $page->title and it let me save again. It now works! :)

I did notice when I initially tried to set up the PHP one it included the opening php tag in the code window, but when I changed the Text one to be PHP that opening tag was omitted. I did a test by adding it back in and once again got the 403 error when I tried to save.

Maybe it's something different in 3.0+, but evidently you can no longer include <?php, even though in the Hanna Code usage notes it says "you may use them when/if necessary".

Share this post


Link to post
Share on other sites

@Margie, it's likely that the error you're seeing is due to interference by the mod_security Apache module. Ask your host to disable mod_security and it should resolve your issue.

  • Like 2

Share this post


Link to post
Share on other sites

Has anyone a script to get all specific pages that uses a special hanna code...

give me me all pages with [[my-hanna-code]] in use?

regards mr-fan

Share this post


Link to post
Share on other sites
5 hours ago, mr-fan said:

Has anyone a script to get all specific pages that uses a special hanna code...

give me me all pages with [[my-hanna-code]] in use?

You can search for the text string that makes up the start of the tag (to allow for varying attributes).

// Get fields with TextformatterHannaCode applied
$hanna_fields = array();
foreach($fields as $field) if(is_array($field->textformatters) && in_array('TextformatterHannaCode', $field->textformatters)) $hanna_fields[] = $field->name;
// Implode for use in selector string
$hanna_fields = implode('|', $hanna_fields);
// Find pages with a given Hanna tag
$has_hanna = $pages->find("$hanna_fields*=[[your_tag");

 

  • Like 2

Share this post


Link to post
Share on other sites

Thank you Robin - will try asap!
[ot]At the moment i'm a little but lethal snuffy...and could not think clearly (i think it is deadly man-flu). So don't think i'm to lazy to search a solution...i'm not...i've read your code and it was clear for me that my question was silly...i'm just standing a little beside me but i think that the peak of my desease is done. :lol:[/ot]

Best regards mr-fan

  • Like 1

Share this post


Link to post
Share on other sites

I'm using Hanna code to embed content from different pages on a site. What I would need is a way to get the created and modified date of the page that has been embedded. I need to use/show these dates in the front-end of the page that has the embedded content. Is there some elegant way I could get this information?

Share this post


Link to post
Share on other sites
Posted (edited)
16 minutes ago, nikoka said:

I'm using Hanna code to embed content from different pages on a site. What I would need is a way to get the created and modified date of the page that has been embedded. I need to use/show these dates in the front-end of the page that has the embedded content. Is there some elegant way I could get this information?

I always get confused about this. Try accessing it using wire('page') and see if that helps.

Quote

The $page API variable available to your Hanna code represents the page where the Hanna code exists.It is possible for this to be different from wire('page'), which represents the page that originated the request.

From the PHP Usage notes section on here

http://modules.processwire.com/modules/process-hanna-code/

Edited by kongondo

Share this post


Link to post
Share on other sites

Thanks @kongondo, I was a bit unclear, I have a page (let's call it page A) with and embedded page (let's call it page B). I need to show the modified/created dates of page B on page A. But how do I get this information from the embedded page B to the "wrapper" page A?   

Share this post


Link to post
Share on other sites
7 hours ago, nikoka said:

Thanks @kongondo, I was a bit unclear, I have a page (let's call it page A) with and embedded page (let's call it page B). I need to show the modified/created dates of page B on page A. But how do I get this information from the embedded page B to the "wrapper" page A?   

What does your hanna code look like? 

Share this post


Link to post
Share on other sites
10 hours ago, kongondo said:

What does your hanna code look like? 

The tag I use for adding embedded page content is: [[single-source url=""]] For the url I add the page ID and the content is then shown. There's a bunch of other things happening, but the essence of the hanna code for getting the embedded page content goes like this: 

$return = $attr["url"];
$id = (int) $return;
$embeddedPage = $pages->get($id);
echo $embeddedPage->body;

 

Share this post


Link to post
Share on other sites
Posted (edited)
2 hours ago, nikoka said:

The tag I use for adding embedded page content is: [[single-source url=""]] For the url I add the page ID and the content is then shown. There's a bunch of other things happening, but the essence of the hanna code for getting the embedded page content goes like this: 


$return = $attr["url"];
$id = (int) $return;
$embeddedPage = $pages->get($id);
echo $embeddedPage->body;

 

I must be missing something then. Do you:

  1. Want to grab $embeddedPage and use it later on in your page or
  2. Want to echo $embeddedPage properies (body, created, etc) right within your Hanna Code?

If #2, you are already doing it by echo $embeddedPage->body. E.g., the following works correctly for me (code in the Hanna Code itself)

$return = $attr["url"];
$id = (int) $return;
$embeddedPage = $pages->get($id);
echo $embeddedPage->body;
$modified = $embeddedPage->modified;
echo date("l jS \of F Y h:i:s A", $modified);

I have this Hanna Code Tag in Page A, where 1049 is the ID of Page B.

[[test url=1049]]

That outputs Page B's modified date.

But this seems too easy. I have a feeling I'm still not getting you.

Edited by kongondo
  • Like 2

Share this post


Link to post
Share on other sites
5 minutes ago, kongondo said:

I must be missing something then. Do you:

  1. Want to grab $embeddedPage and use it later on in your page or
  2. Want to echo $embeddedPage properies (body, created, etc) right within your Hanna Code?

If #2, you are already doing it by echo $embeddedPage->body. E.g., the following works correctly for me (code in the Hanna Code itself)


$return = $attr["url"];
$id = (int) $return;
$embeddedPage = $pages->get($id);
echo $embeddedPage->body;
$modified = $embeddedPage->modified;
echo date("l jS \of F Y h:i:s A", $modified);

I have this Hanna Code Tag in Page A, where 1049 is the ID of Page B.


[[test url=1049]]

That outputs Page B's modified date.

But this seems too easy. I have a feeling I'm still not getting you.

Thanks for sticking with me @kongondo :) Number 1 is what I want to do. I need to use the modified/created dates of Page B to compare to the modified/created dates of Page A and insert some badges on Page A according to which of these pages have been updated more recently. 

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By bernhard
      WHY?
      This module was built to fill the gap between simple $pages->find() operations and complex SQL queries.
      The problem with $pages->find() is that it loads all pages into memory and that can be a problem when querying multiple thousands of pages. Even $pages->findMany() loads all pages into memory and therefore is a lot slower than regular SQL.
      The problem with SQL on the other hand is, that the queries are quite complex to build. All fields are separate tables, some repeatable fields use multiple rows for their content that belong to only one single page, you always need to check for the page status (which is not necessary on regular find() operations and therefore nobody is used to that).
      In short: It is far too much work to efficiently and easily get an array of data based on PW pages and fields and I need that a lot for my RockGrid module to build all kinds of tabular data.

      Basic Usage

       
      Docs & Download
      https://modules.processwire.com/modules/rock-finder/
      https://gitlab.com/baumrock/RockFinder/tree/master
       
      Changelog
      180817, v1.0.6, support for joining multiple finders 180810, v1.0.5, basic support for options fields 180528, v1.0.4, add custom select statement option 180516, change sql query method, bump version to 1.0.0 180515, multilang bugfix 180513, beta release <180513, preview/discussion took place here: https://processwire.com/talk/topic/18983-rocksqlfinder-highly-efficient-and-flexible-sql-finder-module/
    • By OLSA
      Hello for all,
      ConfigurationForm fieldtype module is one my experiment from 2016.
      Main target to build this module was to store multiple setup and configuration values in just 1 field and avoid to use 1 db table to store just single "number of items on page", or another db table to store "layout type" etc. Thanks to JSON formatted storage this module can help you to reduce number of PW native fields in project, save DB space, and reduce number of queries at front-end.
      Install and setup:
      Download (at the bottom ), unzip and install like any other PW module (site/modules/...). Create some filed using this type of field (ConfigurationForm Fieldtype) Go to field setup Input tab and drag some subfields to container area (demo). Set "Name" and other params for subfields Save and place field to templates ("Action tab") How to use it:
      In my case, I use it to store setup and configurations values, but also for contact details, small content blocks... (eg. "widgets").
      Basic usage example:
      ConfigForm fieldtype "setup" has subfields:
      "limit", type select, option values: 5, 10, 15, 20
      "sort", type select, option values: "-date", "date",  "-sort", "sort"
      // get page children (items) $limit = isset($page->setup->limit) ? $page->setup->limit : 10; $sort = isset($page->setup->sort) ? $page->setup->sort : '-sort'; $items = $page->children("limit=$limit, sort=$sort");  
      Screenshots:


       
      Notes:
      Provide option to search inside subfields Provide multilanguage inputs for text and textarea field types Provide option for different field layout per-template basis Do not place/use field type "Button" or "File input" because it won't works. Please read README file for more details and examples Module use JSON format to store values. Text and textarea field types are multilanguage compatible, but please note that main target for this module was to store setup values and small content blocks and save DB space. Search part inside JSON is still a relatively new in MySQL (>=5.77) and that's on you how and for what to use this module.
      Thanks:
      Initial point for this fieldtype was jQuery plugin FormBuiled and thanks to Kevin Chappel for this plugin.
      In field type "link" I use javascript part from @marcostoll module and thanks to him for that part.
      Download:
      FieldtypeConfigForm.zip
      Edit: 14. August 2018. please delete/uninstall previously downloaded zip
      Regards.
         
    • By bernhard
      @Sergio asked about the pdf creation process in the showcase thread about my 360° feedback/survey tool and so I went ahead and set my little pdf helper module to public.
      Description from PW Weekly:
       
      Modules Directory: https://modules.processwire.com/modules/rock-pdf/
      Download & Docs: https://gitlab.com/baumrock/RockPdf
       
      You can combine it easily with RockReplacer: 
      See also a little showcase of the RockPdf module in this thread:
       
    • By Thomas Diroll
      Hi guys I'm relatively new to PW and just finished developing a page for a client. I was able to include all necessary functionality using the core fieldtypes but now I it seems that I need to extend them with a custom one. What I need is a simple button, that copies the absolute url (frontend not PW-backend) of the page which is currently edited to the clipboard. As this feature is only needed inside a specific template, I tend to use a custom fieldtype which provides this feature. I've been looking inside the core modules code (eg. FieldtypeCheckbox.module) but I don't really get the structure of it and how its rendered to the admin page. I also didn't find a lot of tutorials covering custom fieldtypes.
      Maybe some of you could give me some tips on how to write a basic custom fieldtype that renders a button which copies the value of
      page->httpUrl() to the clipboard using JS. Thanks!
    • By bernhard
      Some of you might have followed the development of this module here: https://processwire.com/talk/topic/15524-previewdiscussion-rockdatatables/ . It is the successor of "RockDataTables" and requires RockFinder to get the data for the grid easily and efficiently. It uses the open source part of agGrid for grid rendering.
       
      WHY?
      ProcessWire is awesome for creating all kinds of custom backend applications, but where it is not so awesome in my opinion is when it comes to listing this data. Of course we have the built in page lister and we have ListerPro, but none of that solutions is capable of properly displaying large amounts of data, for example lists of revenues, aggregations, quick and easy sorts by the user, instant filter and those kind of features. RockGrid to the rescue 😉 
       
      Features/Highlights:
      100k+ rows Instant (client side) filter, search, sort (different sort based on data type, eg "lower/greater than" for numbers, "contains" for strings) extendable via plugins (available plugins at the moment: fullscreen, csv export, reload, batch-processing of data, column sum/statistics, row selection) all the agGrid features (cell renderers, cell styling, pagination, column grouping etc) vanilla javascript, backend and frontend support (though not all plugins are working on the frontend yet and I don't plan to support it as long as I don't need it myself)  
      Limitations:
      While there is an option to retrieve data via AJAX the actual processing of the grid (displaying, filtering, sorting) is done on the client side, meaning that you can get into troubles when handling really large datasets of several thousands of rows. agGrid should be one of the most performant grid options in the world (see the official example page with a 100k row example) and does a lot to prevent problems (such as virtual row rendering), but you should always have this limitation in mind as this is a major difference to the available lister options that do not have this limitation.
      Currently it only supports AdminThemeUikit and I don't plan to support any other admin theme.
       
      Download: https://gitlab.com/baumrock/RockGrid
      Installation: https://gitlab.com/baumrock/RockGrid/wikis/Installation
      Quikckstart: https://gitlab.com/baumrock/RockGrid/wikis/quickstart
      Further instructions: https://gitlab.com/baumrock/RockGrid/wikis/quickstart#further-instructions
       
      Module status: alpha, License: MIT
      Note that every installation and uninstallation sends an anonymous google analytics event to my google analytics account. If you don't want that feel free to remove the appropriate lines of code before installation/uninstallation.
       
      Contribute:
      You can contribute to the development of this and other modules or just say thank you by
      testing, reporting issues and making PRs at gitlab liking this post buying me a drink: paypal.me/baumrock/5 liking my facebook page: facebook.com/baumrock hiring me for pw work: baumrock.com  
      Support: Please note that this module might not be as easy and plug&play as many other modules. It needs a good understanding of agGrid (and JavaScript in general) and it likely needs some looks into the code to get all the options. Please understand that I can not provide free support for every request here in the forum. I try to answer all questions that might also help others or that might improve the module but for individual requests I offer paid support for 60€ per hour.
       
      Changelog
      180730 support subdir installations 180711 bugfix (naming issue) 180630 alpha realease  
      Use Cases / Examples:
      Colored grid cells, Icons, Links etc. The Grid also has a "batcher" feature built in that helps communicating with the server via AJAX and managing resource intensive tasks in batches:

      Filters, PW panel links and instant reload on panel close:

      You can combine the grid with a chart library like I did with the (outdated) RockDataTables module: