Jump to content

LMX

Clients
  • Posts

    15
  • Joined

  • Last visited

Reputation Activity

  1. Thanks
    LMX reacted to Nathan Explosion in Inspecting IPS Classes   
    He would be if it was available to install. Also if he wasn't on Cloud, where you can't turn on In_dev. And also because of the last paragraph of the description of the app.
  2. Thanks
    LMX reacted to CoffeeCake in Inspecting IPS Classes   
    You might be interested in this:
     
  3. Like
    LMX got a reaction from bfarber in Developing on Cloud Hosted Version   
    Hello to whomever may stumble upon this! 

    I work for a small organization that doesn't have the capacity to support a self hosted solution but still needed to extend upon the base functionality of the website. This means I don't have access to the developer console - as a result I have been experimenting over the last month or so with development on the cloud hosted version. While not ideal I have been able to accomplish some features that have been useful for us.  If you are in a similar situation I hope this can be useful for you as well and perhaps save you some time.

    If you read this and think there are better ways to achieve these means I would be very happy to learn them. Please do share any ideas you may have if you care to do so!

    Here is an example of a Community Map we built via PHP & HTML custom blocks.
    PHP Block for getting member data - template key = "php_template_key"
    Standard API request as outlined in the docs with the addition of setting the returned data in the global $_SESSION variable to make it accessible from the front end HTML block. (thanks to @bfarber for that idea!).
    $communityUrl = 'BASE_URL_HERE'; $apiKey = 'API_KEY_HERE'; $endpoint = '/core/members?perPage=700'; $curl = curl_init( $communityUrl . 'api' . $endpoint ); curl_setopt_array( $curl, array( CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_HTTPAUTH => CURLAUTH_BASIC, CURLOPT_USERPWD => "{$apiKey}:", CURLOPT_USERAGENT => "MyUserAgent/1.0" )); $response = curl_exec( $curl ); $_SESSION['apiResponseVariable'] = json_encode($response,JSON_HEX_APOS|JSON_HEX_QUOT); Since I only need member name, a custom field and their location I could (and probably should) groom the data here on the BE before passing to the front end. 
     
    HTML Block for rendering map
    This requires you to enable Google Maps Third-party Enhancement at 'YOUR-DOMAIN/admin/?app=core&module=applications&controller=enhancements'.
    Some useful docs for working with the Google Maps API:
    https://developers.google.com/maps/documentation/javascript/adding-a-google-map
    https://developers.google.com/maps/documentation/javascript/marker-clustering
    {block="php_template_key"} {{$response = $_SESSION['apiResponseVariable'];}} <html> <head> <title>Community Map</title> <script src="https://unpkg.com/@google/markerclustererplus@4.0.1/dist/markerclustererplus.min.js"></script> <script src="https://maps.googleapis.com/maps/api/js?key=API_KEY&callback=initMap&libraries=&v=weekly" defer ></script> <style type="text/css"> #map { height: 400px; width: 100%; } .welcome-text { padding-bottom: 20px; } .welcome-text span { font-size: 16px; } </style> <script> function initMap() { let mapStyleOptions = [ { featureType: "water", elementType: "geometry", stylers: [ { color: "#d0d3d4" } ] }, { featureType: "landscape", elementType: "geometry", stylers: [ { color: "#dee2e3" } ], }, { featureType: "road", elementType: "geometry", stylers: [ { visibility: "off" } ], }]; const myMap = new google.maps.Map(document.getElementById("map"), { zoom: 2.5, center: {lat:24.63940428579627, lng:-50.6783944937192}, styles: mapStyleOptions, }); /* This is the messy bit of conforming the $apiResponseVariable to usable json */ let data = '{json_decode($response, TRUE)}'; data = data.replace('{json_decode("', ''); data = data.replace('", TRUE)}', ''); data = JSON.parse(data); let locations = []; let markers = []; let infowindow = new google.maps.InfoWindow(); data.results.forEach(member => { let memberLoc = JSON.parse(member.customFields[1].fields[2].value); if(memberLoc.lat !== null && memberLoc.long !== null) { let organization = member.customFields[1].fields[3].value; let memberName = member.formattedName; let memberUrl = member.profileUrl; let displayName = memberName; if (memberName != organization && organization != '') { displayName = memberName + ' - ' + organization; } locations.push({ id: memberLoc.lat.toString() + memberLoc.long.toString(), name: displayName, profileUrl: member.profileUrl, lat: memberLoc.lat, lng: memberLoc.long }); }; }); const uniqueLocations = Array.from(new Set(locations.map(a => a.id))) .map(id => { return locations.find(a => a.id === id) }); for (i = 0; i < uniqueLocations.length; i++) { marker = new google.maps.Marker({ position: new google.maps.LatLng(uniqueLocations[i].lat, uniqueLocations[i].lng), icon: { url: "some-custom-image-url", }, }); markers.push(marker); google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() { let UrlElement = '<a href="' + uniqueLocations[i].profileUrl + '">' + uniqueLocations[i].name + '</a>'; infowindow.setContent(UrlElement); infowindow.open(myMap, marker); } })(marker, i)); } let clusterImagePath = 'some-custom-image-url' new MarkerClusterer(myMap, markers, { imagePath: clusterImagePath, height: '100px', width: '100px', }); } </script> </head> <body> <div class="welcome-text"><h2>Welcome to the community map!</h2><span>Use our Community Map below to find and interact with other members.</span></div> <!--The div element for the map --> <div id="map"></div> </body> </html>
    I've used this pattern of BE API request and FE PHTML/JS jumble to achieve a fair amount of custom tooling so far (in the absence of access to the developer console). Hope this is useful to someone out there.  Happy to answer any questions or receive feedback.
    Peace love and chicken grease.
     
  4. Thanks
    LMX got a reaction from Zdeněk Tůma in Developing on Cloud Hosted Version   
    Hello to whomever may stumble upon this! 

    I work for a small organization that doesn't have the capacity to support a self hosted solution but still needed to extend upon the base functionality of the website. This means I don't have access to the developer console - as a result I have been experimenting over the last month or so with development on the cloud hosted version. While not ideal I have been able to accomplish some features that have been useful for us.  If you are in a similar situation I hope this can be useful for you as well and perhaps save you some time.

    If you read this and think there are better ways to achieve these means I would be very happy to learn them. Please do share any ideas you may have if you care to do so!

    Here is an example of a Community Map we built via PHP & HTML custom blocks.
    PHP Block for getting member data - template key = "php_template_key"
    Standard API request as outlined in the docs with the addition of setting the returned data in the global $_SESSION variable to make it accessible from the front end HTML block. (thanks to @bfarber for that idea!).
    $communityUrl = 'BASE_URL_HERE'; $apiKey = 'API_KEY_HERE'; $endpoint = '/core/members?perPage=700'; $curl = curl_init( $communityUrl . 'api' . $endpoint ); curl_setopt_array( $curl, array( CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_HTTPAUTH => CURLAUTH_BASIC, CURLOPT_USERPWD => "{$apiKey}:", CURLOPT_USERAGENT => "MyUserAgent/1.0" )); $response = curl_exec( $curl ); $_SESSION['apiResponseVariable'] = json_encode($response,JSON_HEX_APOS|JSON_HEX_QUOT); Since I only need member name, a custom field and their location I could (and probably should) groom the data here on the BE before passing to the front end. 
     
    HTML Block for rendering map
    This requires you to enable Google Maps Third-party Enhancement at 'YOUR-DOMAIN/admin/?app=core&module=applications&controller=enhancements'.
    Some useful docs for working with the Google Maps API:
    https://developers.google.com/maps/documentation/javascript/adding-a-google-map
    https://developers.google.com/maps/documentation/javascript/marker-clustering
    {block="php_template_key"} {{$response = $_SESSION['apiResponseVariable'];}} <html> <head> <title>Community Map</title> <script src="https://unpkg.com/@google/markerclustererplus@4.0.1/dist/markerclustererplus.min.js"></script> <script src="https://maps.googleapis.com/maps/api/js?key=API_KEY&callback=initMap&libraries=&v=weekly" defer ></script> <style type="text/css"> #map { height: 400px; width: 100%; } .welcome-text { padding-bottom: 20px; } .welcome-text span { font-size: 16px; } </style> <script> function initMap() { let mapStyleOptions = [ { featureType: "water", elementType: "geometry", stylers: [ { color: "#d0d3d4" } ] }, { featureType: "landscape", elementType: "geometry", stylers: [ { color: "#dee2e3" } ], }, { featureType: "road", elementType: "geometry", stylers: [ { visibility: "off" } ], }]; const myMap = new google.maps.Map(document.getElementById("map"), { zoom: 2.5, center: {lat:24.63940428579627, lng:-50.6783944937192}, styles: mapStyleOptions, }); /* This is the messy bit of conforming the $apiResponseVariable to usable json */ let data = '{json_decode($response, TRUE)}'; data = data.replace('{json_decode("', ''); data = data.replace('", TRUE)}', ''); data = JSON.parse(data); let locations = []; let markers = []; let infowindow = new google.maps.InfoWindow(); data.results.forEach(member => { let memberLoc = JSON.parse(member.customFields[1].fields[2].value); if(memberLoc.lat !== null && memberLoc.long !== null) { let organization = member.customFields[1].fields[3].value; let memberName = member.formattedName; let memberUrl = member.profileUrl; let displayName = memberName; if (memberName != organization && organization != '') { displayName = memberName + ' - ' + organization; } locations.push({ id: memberLoc.lat.toString() + memberLoc.long.toString(), name: displayName, profileUrl: member.profileUrl, lat: memberLoc.lat, lng: memberLoc.long }); }; }); const uniqueLocations = Array.from(new Set(locations.map(a => a.id))) .map(id => { return locations.find(a => a.id === id) }); for (i = 0; i < uniqueLocations.length; i++) { marker = new google.maps.Marker({ position: new google.maps.LatLng(uniqueLocations[i].lat, uniqueLocations[i].lng), icon: { url: "some-custom-image-url", }, }); markers.push(marker); google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() { let UrlElement = '<a href="' + uniqueLocations[i].profileUrl + '">' + uniqueLocations[i].name + '</a>'; infowindow.setContent(UrlElement); infowindow.open(myMap, marker); } })(marker, i)); } let clusterImagePath = 'some-custom-image-url' new MarkerClusterer(myMap, markers, { imagePath: clusterImagePath, height: '100px', width: '100px', }); } </script> </head> <body> <div class="welcome-text"><h2>Welcome to the community map!</h2><span>Use our Community Map below to find and interact with other members.</span></div> <!--The div element for the map --> <div id="map"></div> </body> </html>
    I've used this pattern of BE API request and FE PHTML/JS jumble to achieve a fair amount of custom tooling so far (in the absence of access to the developer console). Hope this is useful to someone out there.  Happy to answer any questions or receive feedback.
    Peace love and chicken grease.
     
  5. Like
    LMX got a reaction from Joel R in Developing on Cloud Hosted Version   
    Hello to whomever may stumble upon this! 

    I work for a small organization that doesn't have the capacity to support a self hosted solution but still needed to extend upon the base functionality of the website. This means I don't have access to the developer console - as a result I have been experimenting over the last month or so with development on the cloud hosted version. While not ideal I have been able to accomplish some features that have been useful for us.  If you are in a similar situation I hope this can be useful for you as well and perhaps save you some time.

    If you read this and think there are better ways to achieve these means I would be very happy to learn them. Please do share any ideas you may have if you care to do so!

    Here is an example of a Community Map we built via PHP & HTML custom blocks.
    PHP Block for getting member data - template key = "php_template_key"
    Standard API request as outlined in the docs with the addition of setting the returned data in the global $_SESSION variable to make it accessible from the front end HTML block. (thanks to @bfarber for that idea!).
    $communityUrl = 'BASE_URL_HERE'; $apiKey = 'API_KEY_HERE'; $endpoint = '/core/members?perPage=700'; $curl = curl_init( $communityUrl . 'api' . $endpoint ); curl_setopt_array( $curl, array( CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_HTTPAUTH => CURLAUTH_BASIC, CURLOPT_USERPWD => "{$apiKey}:", CURLOPT_USERAGENT => "MyUserAgent/1.0" )); $response = curl_exec( $curl ); $_SESSION['apiResponseVariable'] = json_encode($response,JSON_HEX_APOS|JSON_HEX_QUOT); Since I only need member name, a custom field and their location I could (and probably should) groom the data here on the BE before passing to the front end. 
     
    HTML Block for rendering map
    This requires you to enable Google Maps Third-party Enhancement at 'YOUR-DOMAIN/admin/?app=core&module=applications&controller=enhancements'.
    Some useful docs for working with the Google Maps API:
    https://developers.google.com/maps/documentation/javascript/adding-a-google-map
    https://developers.google.com/maps/documentation/javascript/marker-clustering
    {block="php_template_key"} {{$response = $_SESSION['apiResponseVariable'];}} <html> <head> <title>Community Map</title> <script src="https://unpkg.com/@google/markerclustererplus@4.0.1/dist/markerclustererplus.min.js"></script> <script src="https://maps.googleapis.com/maps/api/js?key=API_KEY&callback=initMap&libraries=&v=weekly" defer ></script> <style type="text/css"> #map { height: 400px; width: 100%; } .welcome-text { padding-bottom: 20px; } .welcome-text span { font-size: 16px; } </style> <script> function initMap() { let mapStyleOptions = [ { featureType: "water", elementType: "geometry", stylers: [ { color: "#d0d3d4" } ] }, { featureType: "landscape", elementType: "geometry", stylers: [ { color: "#dee2e3" } ], }, { featureType: "road", elementType: "geometry", stylers: [ { visibility: "off" } ], }]; const myMap = new google.maps.Map(document.getElementById("map"), { zoom: 2.5, center: {lat:24.63940428579627, lng:-50.6783944937192}, styles: mapStyleOptions, }); /* This is the messy bit of conforming the $apiResponseVariable to usable json */ let data = '{json_decode($response, TRUE)}'; data = data.replace('{json_decode("', ''); data = data.replace('", TRUE)}', ''); data = JSON.parse(data); let locations = []; let markers = []; let infowindow = new google.maps.InfoWindow(); data.results.forEach(member => { let memberLoc = JSON.parse(member.customFields[1].fields[2].value); if(memberLoc.lat !== null && memberLoc.long !== null) { let organization = member.customFields[1].fields[3].value; let memberName = member.formattedName; let memberUrl = member.profileUrl; let displayName = memberName; if (memberName != organization && organization != '') { displayName = memberName + ' - ' + organization; } locations.push({ id: memberLoc.lat.toString() + memberLoc.long.toString(), name: displayName, profileUrl: member.profileUrl, lat: memberLoc.lat, lng: memberLoc.long }); }; }); const uniqueLocations = Array.from(new Set(locations.map(a => a.id))) .map(id => { return locations.find(a => a.id === id) }); for (i = 0; i < uniqueLocations.length; i++) { marker = new google.maps.Marker({ position: new google.maps.LatLng(uniqueLocations[i].lat, uniqueLocations[i].lng), icon: { url: "some-custom-image-url", }, }); markers.push(marker); google.maps.event.addListener(marker, 'click', (function(marker, i) { return function() { let UrlElement = '<a href="' + uniqueLocations[i].profileUrl + '">' + uniqueLocations[i].name + '</a>'; infowindow.setContent(UrlElement); infowindow.open(myMap, marker); } })(marker, i)); } let clusterImagePath = 'some-custom-image-url' new MarkerClusterer(myMap, markers, { imagePath: clusterImagePath, height: '100px', width: '100px', }); } </script> </head> <body> <div class="welcome-text"><h2>Welcome to the community map!</h2><span>Use our Community Map below to find and interact with other members.</span></div> <!--The div element for the map --> <div id="map"></div> </body> </html>
    I've used this pattern of BE API request and FE PHTML/JS jumble to achieve a fair amount of custom tooling so far (in the absence of access to the developer console). Hope this is useful to someone out there.  Happy to answer any questions or receive feedback.
    Peace love and chicken grease.
     
  6. Like
    LMX got a reaction from Zdeněk Tůma in Developing w/ Cloud Hosted Version   
    @bfarber apologies for resurrecting an old thread - quick question.
    If in this example "my_other_block" is a php block which returns an array like below... how would I access the data from that array in the phtml block?
    $exampleArray = Array( 'foo' => 'bar', 'baz' => Array( 'nestedFoo' => 'nestedBar' ) );  
  7. Thanks
    LMX reacted to bfarber in Developing w/ Cloud Hosted Version   
    you'd probably need to do something like this in your block
    $_SESSION['arrayValues'] = ...;// The array data and then look at $_SESSION['arrayValues'] in the rest of the block/template after. I just used $_SESSION as a globally accessible storage container in this case, you could use other similar paradigms.
  8. Thanks
    LMX reacted to bfarber in Developing w/ Cloud Hosted Version   
    $template = \IPS\cms\Templates::load( $key ); $object = $template->_file_object; $url = (string) \IPS\File::get( 'cms_Pages', $object )->url; $key being the appropriate template key
  9. Thanks
    LMX reacted to bfarber in Developing w/ Cloud Hosted Version   
    Within Pages, if you go to Templates in the AdminCP you can create custom CSS and javascript files. When you create individual pages later, you can then choose which CSS or javascript files you wish to embed on which pages, which allows you to separate these resources. That said, this doesn't directly help if you intend to take that custom block and embed it on a different page (i.e. using the sidebar widget manager). You can, however, include those resources still by calling the appropriate URL generator method. It's a bit long winded but would be possible.
    You can create HTML and PHP blocks, and naturally you can embed the two together (either using template logic in an HTML block, or regular PHP methods to output in a PHP block). It's worth noting one block can also embed another block. For instance
    <h2>Title</h2> {block="my_other_block"} You could use this method to hide an environment variable in one block and then embed it in another block, although I'm not really confident this gains you much - if someone could access the first block in the AdminCP, they can access the other block as well.
    Hopefully this helps!
  10. Thanks
    LMX reacted to LoPoSt in Is it possible to rename default apps?   
    Admin CP -- Customization -- Languages click on the globe on the right side then enter blog in the search field
  11. Thanks
    LMX reacted to Morrigan in Adding script tags to <body>   
    Themes > Edit HTML & CSS > Add to globalTemplate
×
×
  • Create New...