GithubHelp home page GithubHelp logo

ad-layers's People

Contributors

bcampeau avatar davisshaver avatar eddiekennedy avatar jaredcobb avatar mboynes avatar onpubcom avatar rdebeasi avatar renatonascalves avatar souvent22 avatar srtfisher avatar timatron avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ad-layers's Issues

Add (thorough) docs

Write up docs in the repo wiki for...

  • Ad ops people
  • Developers implementing the plugin
  • Developers extending the plugin
    • This should break down everything that needs to be implemented in an ad server class extension, step-by-step, and should contain a heavily-commented boilerplate starter class

Add ability to optionally define ad units in code

It would sometimes be preferable to define ad units in code instead of via the settings page. We should offer a filter to populate the ads, and if the filter returns a non-null value, remove the panel in the settings screen.

Add built-in support for Google AMP

Ideally, from a developer's perspective, this should be implemented such that the developer would call:

do_action( 'ad_layers_render_amp_ad_unit', $slot );

And the ad would render as an <amp-ad> element. This would probably involve adding a checkbox to the ad layer UI to flag a layer as a "Google AMP Ad Layer" if the AMP plugin is active.

Ad_Layers_DFP::sanitize_key() is stripping valid Ad Unit code characters

Ad_Layers_DFP::sanitize_key() strips valid Ad Unit code characters such as: '-', '_', '*", etc. Per the DFP docs here is the full list of supported characters:

Ad unit codes
Ad unit codes can be up to 100 characters in length and must be unique. Only letters, numbers, underscores, hyphens, periods, asterisks, forward slashes, backslashes, exclamation marks, left angle brackets, colons and parentheses are allowed.

More info: https://support.google.com/dfp_premium/answer/1628457?hl=en

This is leading to arrays that have different keys than the actual Ad Unit name. For example, within Ad_Layers_DFP::ad_unit_js():

                printf(
                    "dfpAdUnits[%s] = googletag.%s(%s%s,%s)%s%s.addService(googletag.pubads());\n",
                    wp_json_encode( $ad_unit ),
                    $is_oop ? 'defineOutOfPageSlot' : 'defineSlot',
                    wp_json_encode( $this->get_path( $page_type, $ad_unit ) ),
                    // if this is not oop, this is an additional arg to the
                    // method call, and is prefixed with a comma:
                    $is_oop ? '' : ',' . wp_json_encode( $this->default_by_unit[ $ad_unit ] ),
                    wp_json_encode( $this->get_ad_unit_id( $ad_unit ) ),
                    ( ! empty( $this->mapping_by_unit[ $ad_unit ] ) && ! in_array( $ad_unit, $this->oop_units ) ) ? '.defineSizeMapping(mapping' . $this->sanitize_key( $ad_unit ) . ')' : '',
                    ( ! empty( $this->targeting_by_unit[ $ad_unit ] ) ) ? $this->targeting_by_unit[ $ad_unit ] : '' // This is escaped above as it is built
                );

In the above code, if the $ad_unit is named something like 'ad_bigbox', then the (non)matching key in the $this->targeting_by_unit array is actually 'adbigbox' due to sanitize_key() stripping out the '_' character. This is currently preventing the above JS generation logic from working for size mapping and ad-unit level targeting key/values.

Update ad-layers to Node 20 (current lts)

Description

Upgrading the project's Node.js dependency to version 20 (current LTS) will ensure that our software remains supported with the latest security patches and performance improvements. Node.js 20 introduces several new features and optimizations that can enhance application performance and developer productivity. This upgrade will also ensure compatibility with modern libraries and frameworks that require the latest Node.js features.

Acceptance Critiera

  • package.json Engines requires node 20, npm 10
  • Ensure node 20 build and test works locally
    [- CI updated to test node 20 ( Travis -> GitHub Action) will need to be handled in a different ticket]

Use Case

When developers are implementing new features or maintaining existing code, they should have access to the latest JavaScript features, improved diagnostics, and enhanced performance. Upgrading to Node.js 20 will minimize potential security vulnerabilities and compatibility issues with other tools and libraries that depend on newer Node.js versions. This will streamline development workflows and reduce the time spent on troubleshooting and technical debt.

Remove dependence on jQuery

Assuming it's possible to remove jQuery features without compromising backwards compatibility, we should refactor the code to remove the dependence on jQuery. If a site is not using jQuery otherwise, it makes this plugin much heavier than it needs to be.

Duplicate entries in `ad_layers` option

The ad_layers option can somehow get duplicate entries of the Ad Layer posts. When determining the priority, only the first entry matters, but the second entry can be confusing for users.
There is no way to delete the second entry through the GUI, unless you mess with the CSS or DOM in your browser.

Example (note duplicate entries for 1000488, 1000491, 1000608 and others):

array (
  0 => 
  array (
    'post_id' => '1000472',
    'title' => 'Homepage',
  ),
  1 => 
  array (
    'post_id' => '1000488',
    'title' => 'Channel Mains',
  ),
  2 => 
  array (
    'post_id' => '1000491',
    'title' => 'Channel Mains - Article/Video',
  ),
  3 => 
  array (
    'post_id' => '1000493',
    'title' => 'Channel Mains - Photogallery',
  ),
  4 => 
  array (
    'post_id' => '1000608',
    'title' => 'Anglers',
  ),
  5 => 
  array (
    'post_id' => '1000610',
    'title' => 'Anglers - Person Pages',
  ),
  6 => 
  array (
    'post_id' => '1000581',
    'title' => 'Tournaments',
  ),
  7 => 
  array (
    'post_id' => '1000605',
    'title' => 'Other',
  ),
  8 => 
  array (
    'post_id' => '1000603',
    'title' => 'Search Page',
  ),
  9 => 
  array (
    'post_id' => '1000600',
    'title' => 'Video',
  ),
  10 => 
  array (
    'post_id' => '1000593',
    'title' => 'Tournaments - Blog',
  ),
  11 => 
  array (
    'post_id' => '1000595',
    'title' => 'Tournaments - Kayak',
  ),
  12 => 
  array (
    'post_id' => '1000589',
    'title' => 'Tournaments - Basstrakk',
  ),
  13 => 
  array (
    'post_id' => '1000587',
    'title' => 'Tournaments - Leaderboard',
  ),
  14 => 
  array (
    'post_id' => '1000585',
    'title' => 'Tournaments - Individual',
  ),
  15 => 
  array (
    'post_id' => '1000583',
    'title' => 'Tournaments - Schedule',
  ),
  16 => 
  array (
    'post_id' => '1000591',
    'title' => 'Tournaments - Info',
  ),
  17 => 
  array (
    'post_id' => '1000495',
    'title' => 'Channel Mains - Archive',
  ),
  18 => 
  array (
    'post_id' => '117675',
    'title' => 'catch all',
  ),
  19 => 
  array (
    'post_id' => '117673',
    'title' => 'Homepage',
  ),
  20 => 
  array (
    'post_id' => '1000089',
    'title' => 'Catch All',
  ),
  21 => 
  array (
    'post_id' => '1000641',
    'title' => 'Anglers - Standings',
  ),
  22 => 
  array (
    'post_id' => '1000640',
    'title' => 'Anglers - Elites',
  ),
  23 => 
  array (
    'post_id' => '1000488',
    'title' => 'Channel Mains',
  ),
  24 => 
  array (
    'post_id' => '1000631',
    'title' => 'Tournaments - Schedule',
  ),
  25 => 
  array (
    'post_id' => '1000632',
    'title' => 'Tournaments - Individual',
  ),
  26 => 
  array (
    'post_id' => '1000633',
    'title' => 'Tournaments - Leaderboard',
  ),
  27 => 
  array (
    'post_id' => '1000634',
    'title' => 'Tournaments - Basstrakk',
  ),
  28 => 
  array (
    'post_id' => '1000635',
    'title' => 'Tournaments - Kayak',
  ),
  29 => 
  array (
    'post_id' => '1000636',
    'title' => 'Search Page',
  ),
  30 => 
  array (
    'post_id' => '1000637',
    'title' => 'Other',
  ),
  31 => 
  array (
    'post_id' => '1000638',
    'title' => 'Anglers - Person Pages',
  ),
  32 => 
  array (
    'post_id' => '1000639',
    'title' => 'Anglers - Person Pages - Stats',
  ),
  33 => 
  array (
    'post_id' => '1000491',
    'title' => 'Channel Mains - Article/Video',
  ),
  34 => 
  array (
    'post_id' => '1000641',
    'title' => 'Anglers - Standings',
  ),
  35 => 
  array (
    'post_id' => '1000610',
    'title' => 'Anglers - Person Pages',
  ),
  36 => 
  array (
    'post_id' => 1000581,
    'title' => 'Tournaments',
  ),
  37 => 
  array (
    'post_id' => 1000603,
    'title' => 'Search Page',
  ),
  38 => 
  array (
    'post_id' => 1000608,
    'title' => 'Anglers',
  ),
)```

Post types with has_archive can't target singular vs archive

If a post type has an archive, you can't target its singular views vs its archive views.

php/class-ad-layers.php:342-358

// Add single post types
$single_post_types = apply_filters( 'ad_layers_ad_server_single_post_types', wp_list_filter( get_post_types( array( 'public' => true ), 'objects' ), array( 'label' => false ), 'NOT' ) );
if ( ! empty( $single_post_types ) ) {
    foreach ( $single_post_types as $post_type ) {
        if ( Ad_Layers_Post_Type::instance()->get_post_type() != $post_type->name ) {
            $page_types[ $post_type->name ] = $post_type->label;
        }
    }
}
// Add archived post types
$archived_post_types = apply_filters( 'ad_layers_ad_server_archived_post_types', wp_list_filter( get_post_types( array( 'has_archive' => true ), 'objects' ), array( 'label' => false ), 'NOT' ) );
if ( ! empty( $archived_post_types ) ) {
    foreach ( $archived_post_types as $post_type ) {
        $page_types[ $post_type->name ] = $post_type->label . __( ' Archive', 'ad-layers' );
    }
}

In the above, the array key $page_types[ $post_type->name ] is used in both places. Since the post type is used as the targeting key for both, you can't differentiate between them.

Script tag are being stripped out on VIP Platform

While serving the ad-layers through widgets, script tag is being stripped out, leaving the javascript code to be displayed on the site. How can we fix or is there something I am doing wrong ?

Cause : In plugins/ad-layers/php/class-ad-layers-widget.php , on line no.50 "wp_kses_post" is stripping the <script tag>.

How to resolve that ?

targeting_js function in class-ad-layers-dfp.php does not output anything

Current targeting_js function:

<?php
        private function targeting_js( $ad_layer ) {
            // Handle any page level custom targeting specified for this ad layer.
            $custom_targeting = get_post_meta( $ad_layer['post_id'], 'ad_layer_custom_targeting', true );
            $custom_targeting = apply_filters( 'ad_layers_dfp_page_level_targeting', $custom_targeting );

            if ( empty( $custom_targeting ) ) {
                return;
            }

            // Add the JS
            if ( ! empty( $targeting_values ) ) {
                echo 'googletag.pubads()' . $this->get_targeting_js_from_array( $custom_targeting ) . ";\n";
            }
        }
?>

As can be seen above, JS only gets echo'd if $targeting_values is not empty, yet $targeting_values is not a variable that exists for this function, resulting in the echo statement never being able to run.

Take advantage of autoloaders for including new Ad Servers

Reference #82

Composer has support for generating an autoloader for you so you can "just use" the class and it will load the file on demand.

We'd probably need a class-map autoloader. https://getcomposer.org/doc/04-schema.md#classmap

The downside to a class-map autoloader is that it's really unintelligent and needs to be regenerated when you add a new file or rename an existing file. In OO programming where you potentially are creating new classes all the time, that's a hassle and so PSR-4 and PSR-12 were adopted so that loading classes can be inferred by convention. https://www.php-fig.org/psr/psr-4/

Add Gutenberg block

Ad Layers presently has a shortcode to render an ad unit. It should also include a Gutenberg block, which should:

  • Have the option of selecting an ad unit to render, and render a preview (not a real ad)
  • Render the block in the appropriate size for the unit
  • If the ad unit has multiple sizes, offer the user the ability to toggle between the preview sizes

Lazy load and debug mode

When in debug mode, ads built using AdLayersAPI.lazyLoadAd() don't render with placeholders. This would be extremely valuable to have.

Feature/tool for importing/exporting ad layer config between sites

Overview:

There is no way presently to easily import/export ad server and ad layer configurations between environments. Considering that these configuration options are often needed to be identical between testing environments and production environments, an admin dashboard tool/feature for this purpose would streamline a lot of effort and remove complexity/complication for the maintenance of ad layer configurations across multiple environments.

Proposed User Story:

As an editor/maintainer of an ad layers implementation, I should be able to export and import ad layer configuration options to and from other sites.

Proposed MVP:

  • Add an additional "Import/Export" submenu page to the Ad Layers menu option
  • An option to export all ad server configuration
  • An option to export all ad layer configuration (this would require taxonomy terms to exist in parity between environments)
  • Export entire ad layer configuration (layers and server settings)
  • Import configuration options (since this process needs to be done in a specific order - i.e. layers can't be created without first having ad units created - the tool/feature should be smart enough to determine what is being imported and in what order it needs to happen)

Implementation ideas:

  • This could perhaps leverage custom REST endpoints. (see #54?)
  • This should be fully functional from within the WP dash

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.