Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display Altmetric badges on simple item view #2400

Open
alanorth opened this issue Jul 26, 2023 · 5 comments · May be fixed by #2496
Open

Display Altmetric badges on simple item view #2400

alanorth opened this issue Jul 26, 2023 · 5 comments · May be fixed by #2496
Assignees
Labels
help wanted Needs a volunteer to claim to move forward new feature

Comments

@alanorth
Copy link
Contributor

alanorth commented Jul 26, 2023

Is your feature request related to a problem? Please describe.
In earlier versions of DSpace we had the ability to display Altmetric badges on item views based on an item's DOI or Handle (the dspace/config/modules/altmetrics.cfg configuration still exists in the DSpace 7 backend, though it is is not working).

Describe the solution you'd like
The ability to display Altmetric donuts on an item view based on the item's metadata. If the item has a DOI then it should be checked first, followed by the Handle. There are API endpoints for both types of identifiers, which return SVG images. In previous versions it was possible to configure the appearance of the badge (size, popup location, etc).

For example, see this DSpace 6 repository with both Altmetric and Dimensions badges:

Screenshot 2023-07-26 at 19-46-38 Planetary boundaries Guiding human development on a changing planet-fs8

(Bonus points for the closely related Dimensions.ai badge).

@alanorth alanorth added new feature needs triage New issue needs triage and/or scheduling and removed needs triage New issue needs triage and/or scheduling labels Jul 26, 2023
@alanorth alanorth added this to the 8.0 milestone Jul 26, 2023
@alanorth alanorth changed the title Display Altmetric badges Display Altmetric badges on simple item view Jul 26, 2023
@tdonohue tdonohue added the help wanted Needs a volunteer to claim to move forward label Jul 26, 2023
@arvoConsultores arvoConsultores self-assigned this Aug 2, 2023
@alanorth
Copy link
Contributor Author

alanorth commented Sep 4, 2023

I've done a rudimentary implementation of this in a field component:

src/app/item-page/simple/field-components/specific-field/altmetric/item-page-altmetric-field.component.ts
import { Component, Input, AfterViewInit } from '@angular/core';

import { Item } from '../../../../../core/shared/item.model';
import { ItemPageFieldComponent } from '../item-page-field.component';

@Component({
  selector: 'ds-item-page-altmetric-field',
  templateUrl: './item-page-altmetric-field.component.html'
})
/**
 * This component renders an Altmetric badge.
 * It expects 1 parameter: The item
 */
export class ItemPageAltmetricFieldComponent extends ItemPageFieldComponent implements AfterViewInit {
  // Is this hacky? It feels hacky. I can't figure out any other way to load the
  // Altmetric embed.js *after* Angular finishes rendering the DOM.
  ngAfterViewInit() {
    // Altmetric embed.js
    import('./embed.js');
  }

  /**
   * The item to display metadata for
   */
  @Input() item: Item;

  /**
   * Helper function to extract the DOI itself from a URI. Should return the
   * DOI component for any variation of http, https, dx.doi.org, and doi.org.
   * @type {string}
   */
  parseDoi(doi: string) {
    const regex = /https?:\/\/(dx\.)?doi\.org\//gi;
    return doi.replace(regex, '');
  }

  /**
   * Helper function to extract the Handle itself from a URI.
   * @type {string}
   */
  parseHandle(handle: string) {
    const regex = /https?:\/\/hdl\.handle\.net\//gi;
    return handle.replace(regex, '');
  }
}
src/app/item-page/simple/field-components/specific-field/altmetric/item-page-altmetric-field.component.html
<div class="item-page-field">
    <ds-metadata-field-wrapper [hideIfNoTextContent]="false">
        <div class="simple-view-element">
            <div class="simple-view-element-body">
                <ng-container [ngTemplateOutlet]="altmetricBadge"
                              [ngTemplateOutletContext]="{
                                                    itemDoi: item?.firstMetadataValue('cg.identifier.doi'),
                                                    itemHandle: item?.firstMetadataValue('dc.identifier.uri'),
                                                  }">
                </ng-container>
            </div>
        </div>
    </ds-metadata-field-wrapper>
</div>

<!-- See: https://badge-docs.altmetric.com/getting-started.html -->
<ng-template #altmetricBadge let-itemDoi="itemDoi" let-itemHandle="itemHandle">
    <!-- Prefer using the Altmetric score for the DOI if it is present -->
    <div *ngIf="itemDoi.length" class="altmetric-embed" data-hide-no-mentions="true" data-badge-type="donut" data-badge-popover="right" data-link-target="_blank" [attr.data-doi]=parseDoi(itemDoi)></div>
    <!-- If not, check the score for the Handle -->
    <div *ngIf="!itemDoi.length" class="altmetric-embed" data-hide-no-mentions="true" data-badge-type="donut" data-badge-popover="right" data-link-target="_blank" [attr.data-handle]=parseHandle(itemHandle)></div>
</ng-template>

It works, but I am importing a static version of the Altmetric embed.js from the component. The component uses ngAfterViewInit to import the JavaScript after the div containing the DOI or Handle has been added to the DOM. A better implementation on par with DSpace 6 is welcome!

The result in our DSpace 7.6.1 repository is:

Screenshot

@sergius02
Copy link
Contributor

I'm trying this but it seems doesn't fully work for me. When i access to a publication with DOI the badge appears, but if i go back to the collection (or navigate to other page) and return, the badge disappear. I need to full refresh the page with F5 to get it back.

@alanorth
Copy link
Contributor Author

alanorth commented Sep 6, 2023

@sergius02 yes I've seen the same. I think it's because this method imports the Altmetric JavaScript and writes to the DOM after Angular has finished loading and saving the cached version of the page. When you navigate away from the page and back, the browser shows the cached version.

We need a more Angular-friendly solution eventually. Hopefully @arvoConsultores can think of something!

@sergius02
Copy link
Contributor

sergius02 commented Sep 7, 2023

It seems that calling the funtion _altmetric_embed_init after the import('./embed.js') reload the badge.

  ngAfterViewInit() {
    // Altmetric embed.js
    import('./embed.js');
    window['_altmetric_embed_init']();
  }

This is not a clean way but at least it works.

We need a more Angular-friendly solution eventually. Hopefully @arvoConsultores can think of something!

Yes we need something more angular-like solution, i'm the dev assigned to this from @arvoConsultores 😄, thanks for the code!

@alanorth
Copy link
Contributor Author

alanorth commented Sep 7, 2023

You're welcome, @sergius02. I am new to Angular so this was the best I could come up with. I thought I would share to help other people come up with something better! 😄

Another thing that will be an issue is using a static import of embed.js. If Altmetric changes their script then we will be using the old one, which could create problems in the future.

@sergius02 sergius02 linked a pull request Sep 14, 2023 that will close this issue
8 tasks
@tdonohue tdonohue removed this from the 8.0 milestone Jun 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Needs a volunteer to claim to move forward new feature
Projects
Status: 🏗 In Progress
Development

Successfully merging a pull request may close this issue.

4 participants