How to add block-like visibility settings to nodes? I have created a custom content type 'campaign' in my module using hook_node_info() and added fields using hook_field_group_info(). This campaign content type will be shown to users site wide in modals/pop-ups using CTool modal on page load (hook_init()).

What I'm looking for is, to give an option to admins to restrict this pop-up/modal for different roles or paths. Same like block section is doing. For example whether to show a block on node/104 or not, or wether to show a block for (anonymous) users only or not. Like shown in the screenshot below.


My aim is that, while creating 'campaign' nodes, admins should be able to select pages or roles to show that particular campaign or not.

Can you please guide me how can I use Drupal block logic here? Or do you maybe can make some code suggestions I can start with in my custom module?
Block visibility rules are kind of fundamentally different from nodes in that nodes are intended to always show up using the "full" or "default" display mode in the main content block/region of the specific node's unique URL. On the other hand, blocks go hand-in-hand with the ability to be placed in any region on any page.  Block visibility can group permissions (ie role based rules)  along with path-or-url-based rules, but nodes cannot natively do this.

I can think of three possible alternatives (there might be more):

1) Embed Nodes in a block using one of these modules, and then use block visibility rules to place it.  This has the drawback that you have to tie things together quite manually in two places.

2) If you're showing campaign nodes on other nodes, then you can use an entity_reference field to reference the campaign node from another node (or vice versa)  and then just set the entity reference field's display settings to render the entity as if it were a field on the node.

3) Write a completely custom solution to mimic block visibility rules for nodes.  I'd start with a Text (long) field (call it field_campaign_urls),  then in a node_form_alter() hook alter the display to show up in a vertical tab (or you could use Field Group module to do this in the UI).  Then you'd need to implement a hook that gets called on all pages, e.g. hook_page_alter test the internal Drupal URL (and optionally also the pathauto alias) for a match against all values in the field_campaign_urls database table. The challenge here will be writing the wildcard functionality, you'll need to figure out how to convert  some/url/* into a database condition LIKE 'some/url/%'  This is also where you might want to start digging into the block.module code to find out more about the internal structure of how block visibility query logic works.   Finally, you'll need to combine this logic with your custom node access logic as well.  And indeed figure out which block region you want to add your node to.  You may leverage drupal_add_region_content to add your rendered node to a specific region.