Drupal 8: How to customize the block content on specific page - drupal-8

I'm able to change the block content by using the hook as below. But, I would like to change the block content (for eg: system_main_block) only if it appears on specific page. But, I'm not sure how to get the page id or title in the hooks below. Appreciate help.
function yourmodule_block_view_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block)
{
if ($block->getBaseId() === 'system_powered_by_block') {
$build['#pre_render'][] = '_yourmodule_block_poweredby_prerender';
}
}
function _yourmodule_block_poweredby_prerender(array $build) {
$build['content']['#markup'] = Markup::create('Your text');
return $build;
}

You can check the route name like this:
function yourmodule_block_view_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
if ($block->getBaseId() === 'system_powered_by_block' && \Drupal::routeMatch()->getRouteName() === '<your_route_name>') {
$build['#pre_render'][] = '_yourmodule_block_poweredby_prerender';
}
}

Related

Changing image based on location data output

I am trying to show/echo users location on a webpage using maxmind geoip2 paid plan, I also want to show different images based on the state/city names output.
For example, if my webpage shows the user is from New York, I would like to show a simple picture of New York, if the script detects the user is from Washington, the image should load for Washington.
This is the snippet I have tried but doesn't work.
<script type="text/javascript">
if
$('span#region=("New York")') {
// Display your image for New York
document.write("<img src='./images/NY.jpg'>");
}
else {
document.write("<img src='./images/different.jpg'>");
}
</script>
This is the code in the header.
<script src="https://js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js" type="text/javascript"></script>
<script>
var onSuccess = function(geoipResponse) {
var cityElement = document.getElementById('city');
if (cityElement) {
cityElement.textContent = geoipResponse.city.names.en || 'Unknown city';
}
var countryElement = document.getElementById('country');
if (countryElement) {
countryElement.textContent = geoipResponse.country.names.en || 'Unknown country';
}
var regionElement = document.getElementById('region');
if (regionElement) {
regionElement.textContent = geoipResponse.most_specific_subdivision.names.en || 'Unknown region';
}
};
var onError = function(error) {
window.console.log("something went wrong: " + error.error)
};
var onLoad = function() {
geoip2.city(onSuccess, onError);
};
// Run the lookup when the document is loaded and parsed. You could
// also use something like $(document).ready(onLoad) if you use jQuery.
document.addEventListener('DOMContentLoaded', onLoad);
</script>
And this simple span shows the state name in body text of the Html when the page loads.
<span id="region"></span>
now the only issue is the image doesn't change based on users location, what am i doing wrong here?
Your example is missing some code, but it looks like you are running some code immediately and some code in a callback, a better way to do it is to have all the code in the callback:
// whitelist of valid image names
var validImages = ["NJ", "NY"];
// get the main image you want to replace
var mainImage = document.getElementById('mainImage');
if (mainImage) {
// ensure there is a subdivision detected, or load the default
if(geoipResponse.subdivisions[0].iso_code && validImages.includes( && geoipResponse.subdivisions[0].iso_code)){
mainImage.src = "./images/" + geoipResponse.subdivisions[0].iso_code + ".jpg";
} else {
mainImage.src = "./images/different.jpg";
}
}
Then just have the image you want to replace be:
<img src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" id="mainImage" />
Notes:
If you are using a responsive image, make sure your transparent gif is the same ratio height of to width as your final image to avoid page reflows.
You will have to load the different.jpg in the onError callback as well.

In ember, how to change values of checkboxes based on another

I have four checkbox and I want to check automatically checkbox with id = 2 if checkbox with id = 4 is checked.
I did the following but did not get the output. Could someone help me with this.
{#each category in checkboxList}}
{{input id = category.CHECKBOX_ID type="checkbox" checked=category.IS_CHECKED}}
{{#if category.CHECKBOX_ID == 4 && category.IS_CHECKED == true}}
{{action 'CheckSize'}}
{{/if}}
The checkboxList is
[
{"IS_CHECKED":false,"CHECKBOX_ID":1},
{"IS_CHECKED":false,"CHECKBOX_ID":2},
{"IS_CHECKED":true,"CHECKBOX_ID":3},
{"IS_CHECKED":false,"CHECKBOX_ID":4}
]
You'll want to manage the state of the checkboxes separately.
Here is an example I did for another SO question that had a similar problem to solve:
https://ember-twiddle.com/468a737efbbf447966dd83ac734f62ad
The gist of it is
we use a single action in response to a click of any checkbox:
#action
toggleChecked(id) {
const newTree = check(this.options, id);
this.set('options', newTree);
}
In this example (taken from the ember-twiddle), all of the logic is extracted to a pure-function named check.
Check itself is pretty involved, but because the application logic is different between that example and the problem you've run in to, I'll just show the entry point function:
export function check(tree, id, transform = toggle) {
if (tree === undefined) return undefined;
if (Array.isArray(tree)) {
return tree.map(t => check(t, id, transform));
}
if (tree.id === id || id === 'all') {
return checkNode(tree, id, transform);
}
if (tree.children) {
return checkChildren(tree, id, transform);
}
return tree;
}
This is just an example of how you can immutably modify the representation of all checkboxes by using a pure function. Your logic may vary.
Hope this helps :)

Ember CLI -- store.find doesn't work when searching for all results with a given name

I'm trying to search for all employees that have a title of developer
As per the documentation (http://guides.emberjs.com/v1.10.0/models/finding-records/) It seems the correct way to do this is:
return this.store.find('employee', { title: "developer" });
But this is not working in Ember CLI 0.2.2, and I can't even see my template when I try this, even though when I do
return this.store.find('employee')
I can see a list of all employees and there are multiple employees with that title
Turns out I needed to override the DS.FixtureAdapter::queryFixtures method. I went into my adapters/application.js file and added
queryFixtures: function(records, query, type) {
return records.filter(function(record) {
for(var key in query) {
if (!query.hasOwnProperty(key)) { continue; }
var value = query[key];
if (record[key] !== value) { return false; }
}
return true;
});
}

Loopback strange behaviour

I am talking about loopback push component. I am trying to intercept the "create" method of "Installation" model. My code looks like this -
server/boot/installationex.js
module.exports = function (app) {
var Installation = app.models.Installation;
var create = Installation.create;
Installation.create = function (data, cb) {
//reinitializing old implementation
this.create = create;
console.log("Received data: "+JSON.stringify(data));
if (!data || !data.imei) {
console.log("No data or imei was provided, creating new");
this.create(data, cb);
return;
}
//saving 'this' reference
var that = this;
//search by imei filter
var filter = {where: {imei: data.imei}};
this.findOne(filter, function (err, result) {
if (err) {
console.log("Error occurred while looking for installation by IMEI");
cb(err);
return;
}
if (!result) {
console.log("No installation found by IMEI, will create a new installation");
that.create(data, cb);
return;
}
console.log("Found existing installation with id: " + JSON.stringify(result));
result.deviceToken = result.gpsLocation = result.osVersion = result.vendor = result.phoneNumbers = null;
if (data.deviceToken) {
result.deviceToken = data.deviceToken;
}
if (data.gpsLocation) {
result.gpsLocation = data.gpsLocation;
}
if (data.osVersion) {
result.osVersion = data.osVersion;
}
if (data.vendor) {
//result.vendor=data.vendor;
result.vendor = 'jahid';
}
if (data.phoneNumbers) {
result.phoneNumbers = data.phoneNumbers;
}
that.upsert(result, cb);
});
}
}
Unfortunately this code is invoked only once, I mean the first time. After that this code is never invoked. I became sure by looking at the log. It only prints the log first time. After that it does not print any log.
Any idea why this glue code is only invoked once? My intention is to intercept all create method invocation for Installation model. And check if there is already an entry for supplied "IMEI", if so then reuse that. Otherwise create new.
Thanks in advance.
Best regards,
Jahid
What I would start here with is:
instead of implementing your own intercepting mechanism use Model Hooks
check out findOrCreate() method
boot scripts are only run once during application startup. if you want a function that triggers every time a function is called, use a remote hook or model hook. probably something along the lines of:
...
Installation.beforeRemote('create', ...
...
see http://docs.strongloop.com/display/LB/Adding+logic+to+models for more info

Ember.js global routed/transitioned events

Is it possible to subscribe to all transition events in the application? Or alternatively some observable property containing the current route?
I'm integrating with a third-party UI component that needs to be synchronized to the current route.
The application controller has a currentRouteName property, as explained here. It's mostly for debugging, but I imagine that it's a fairly stable property that could be used in production.
EDIT: If you need to be alerted of all changes, use the hashchange event like Ember does internally. This will only work if you're using hash based routing though. If you're using Ember's history API based routing, you'll have to use that.
In your app_controller you can add this snippet which fires on every path/route change
currentPathDidChange: function currentPathDidChange() {
var path = this.get('currentPath')
}.observes('currentPath')
I solved this by hooking into Router.didTransition
Live example: http://jsbin.com/yuzedacu/5/edit (modified the example found here)
App.Router.reopen({
updateCurrentRoute: function(infos) {
var appController = this.container.lookup('controller:application');
if (!('currentRoute' in appController)) {
Ember.defineProperty(appController, 'currentRoute');
}
if (infos && infos.length > 0) {
// The last part of the route contains the route name
var route = infos[infos.length - 1].name;
// Collect the dynamic route parameters
var params = infos.reduce(function(a, b) {
// Parameter can be named anything
// assume there are 0 or 1 parameters
for (var name in b.params) {
if (b.params.hasOwnProperty(name)) {
// 1 parameter
return a.concat(b.params[name]);
}
}
// 0 parameters
return a;
}, []);
var path = [route].concat(params);
Ember.set(appController, 'currentRoute', path);
} else {
Ember.set(appController, 'currentRoute', []);
}
},
didTransition: function(infos) {
this.updateCurrentRoute(infos);
return this._super(infos);
}
});