alleyinteractive / ad-layers Goto Github PK
View Code? Open in Web Editor NEWAd Layers WordPress Plugin
License: Other
Ad Layers WordPress Plugin
License: Other
With the latest version of the plugin, going to the Ad Server Settings (/wp-admin/edit.php?post_type=ad-layer&page=ad_layers_ad_server_settings) page in wp-admin throws the following exception, resulting in a fatal error:
PHP Fatal error: Uncaught exception 'FM_Submenu_Not_Initialized_Exception' with message 'The Fieldmanger context for this submenu was not initialized'
This renders the plugin no longer fully configurable via the wp-admin UI.
Write up docs in the repo wiki for...
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.
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.
Allow for managing settings and layers via the REST API
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.
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.
package.json
Engines requires node 20, npm 10When 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.
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.
It's still working and in use on our sites, but I'm concerned about relying on it in the future. Can someone at the Alley team provide thoughts?
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',
),
)```
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.
Some ad units may share the same sizes so it would facilitate setup if they could be copied.
Create user guide that shows side-by-side instructions how to set things up in both WordPress and DFP (related: #18)
DFP's docs on building responsive ads says:
A browser size mapping of [0, 0] can be used to specify a default mapping that can be used on any browser size.
Setting a width and height of 0 doesn't work in Ad Layers. You can set it to be [1,1]
which works just as well, but [0,0]
should be supported.
The underlying bug is upstream in alleyinteractive/wordpress-fieldmanager#493.
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 ?
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.
The code coverage that Ad Layers has historically enjoyed via Travis should be ported over to GitHub Actions.
Look through the Google Ad Manager API and see what opportunities exist for automating the Google Ad Manager integration in Ad Layers. For example, an integration could look up all available ad units and sync them into Ad Layers to save that laborious setup step.
These two lines aren't going to fly on VIP. This needs to be restricted/escaped in some way.
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/
Ad Layers presently has a shortcode to render an ad unit. It should also include a Gutenberg block, which should:
When in debug mode, ads built using AdLayersAPI.lazyLoadAd()
don't render with placeholders. This would be extremely valuable to have.
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.
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.