Skip to content

JSON-LD Initial Release #8

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

Merged
merged 12 commits into from
Mar 16, 2025
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: [StartAutomating]
510 changes: 510 additions & 0 deletions .github/workflows/JSON-LD-Build.yml

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions Build/GitHub/Jobs/JsonLD.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@{
"runs-on" = "ubuntu-latest"
if = '${{ success() }}'
steps = @(
@{
name = 'Check out repository'
uses = 'actions/checkout@v2'
},
@{
name = 'GitLogger'
uses = 'GitLogging/GitLoggerAction@main'
id = 'GitLogger'
},
@{
name = 'Use PSSVG Action'
uses = 'StartAutomating/PSSVG@main'
id = 'PSSVG'
},
@{
name = 'Use PipeScript Action'
uses = 'StartAutomating/PipeScript@main'
id = 'PipeScript'
},
'RunEZOut',
'RunHelpOut',
@{
name = 'Use PSJekyll Action'
uses = 'PowerShellWeb/PSJekyll@main'
id = 'PSJekyll'
}
)
}
10 changes: 10 additions & 0 deletions Build/GitHub/Steps/PublishTestResults.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@{
name = 'PublishTestResults'
uses = 'actions/upload-artifact@main'
with = @{
name = 'PesterResults'
path = '**.TestResults.xml'
}
if = '${{always()}}'
}

12 changes: 12 additions & 0 deletions Build/JSON-LD.GitHubWorkflow.PSDevOps.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#requires -Module PSDevOps
Import-BuildStep -SourcePath (
Join-Path $PSScriptRoot 'GitHub'
) -BuildSystem GitHubWorkflow

Push-Location ($PSScriptRoot | Split-Path)
New-GitHubWorkflow -Name "JSON-LD Module Build" -On Push,
PullRequest,
Demand -Job TestPowerShellOnLinux,
TagReleaseAndPublish, JsonLD -OutputPath .\.github\workflows\JSON-LD-Build.yml

Pop-Location
69 changes: 69 additions & 0 deletions Commands/Get-JsonLD.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
function Get-JsonLD {
<#
.SYNOPSIS
Gets JSON-LD data from a given URL.
.DESCRIPTION
Gets JSON Linked Data from a given URL.

This is a format used by many websites to provide structured data about their content.
.EXAMPLE
# Want to get information about a movie? Linked Data to the rescue!
Get-JsonLD -Url https://www.imdb.com/title/tt0211915/
.EXAMPLE
# Want information about an article? Lots of news sites use this format.
Get-JsonLD https://www.thebulwark.com/p/mahmoud-khalil-immigration-detention-first-amendment-free-speech-rights
.EXAMPLE
# Want to get information about a schema?
jsonld https://schema.org/Movie
# Get-JSONLD will output the contents of a `@Graph` object if no `@type` is found.
#>
[Alias('jsonLD','json-ld')]
param(
# The URL that may contain JSON-LD data
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[Uri]
$Url
)

begin {
$linkedDataRegex = [Regex]::new(@'
(?<HTML_LinkedData>
<script # Match <script tag
\s{1,} # Then whitespace
type= # Then the type= attribute (this regex will only match if it is first)
[\"\'] # Double or Single Quotes
application/ld\+json # The type that indicates linked data
[\"\'] # Double or Single Quotes
[^>]{0,} # Match anything until the end of the start tag
\> # Match the end of the start tag
(?<JsonContent>(?:.|\s){0,}?(?=\z|</script>)) # Anything until the end tag is JSONContent
)
'@, 'IgnoreCase,IgnorePatternWhitespace','00:00:00.1')
}

process {
$restResponse = Invoke-RestMethod -Uri $Url
foreach ($match in $linkedDataRegex.Matches("$restResponse")) {
foreach ($jsonObject in
$match.Groups['JsonContent'].Value |
ConvertFrom-Json
) {
if ($jsonObject.'@type') {
$schemaType = $jsonObject.'@context',$jsonObject.'@type' -ne '' -join '/'
$jsonObject.pstypenames.insert(0, $schemaType)
$jsonObject
} elseif ($jsonObject.'@graph') {
foreach ($graphObject in $jsonObject.'@graph') {
if ($graphObject.'@type') {
$graphObject.pstypenames.insert(0, $graphObject.'@type')
}
$graphObject
}
} else {
$jsonObject
}

}
}
}
}
26 changes: 26 additions & 0 deletions JSON-LD.ps.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
$commandsPath = Join-Path $PSScriptRoot Commands
[include('*-*')]$commandsPath

$myModule = $MyInvocation.MyCommand.ScriptBlock.Module
$ExecutionContext.SessionState.PSVariable.Set($myModule.Name, $myModule)
$myModule.pstypenames.insert(0, $myModule.Name)

New-PSDrive -Name $MyModule.Name -PSProvider FileSystem -Scope Global -Root $PSScriptRoot -ErrorAction Ignore

if ($home) {
$MyModuleProfileDirectory = Join-Path ([Environment]::GetFolderPath("LocalApplicationData")) $MyModule.Name
if (-not (Test-Path $MyModuleProfileDirectory)) {
$null = New-Item -ItemType Directory -Path $MyModuleProfileDirectory -Force
}
New-PSDrive -Name "My$($MyModule.Name)" -PSProvider FileSystem -Scope Global -Root $MyModuleProfileDirectory -ErrorAction Ignore
}

# Set a script variable of this, set to the module
# (so all scripts in this scope default to the correct `$this`)
$script:this = $myModule

#region Custom
#endregion Custom

Export-ModuleMember -Alias * -Function * -Variable $myModule.Name

35 changes: 35 additions & 0 deletions JSON-LD.psd1
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@{
RootModule = 'JSON-LD.psm1'
ModuleVersion = '0.0.1'
GUID = '4e65477c-012c-4077-87c7-3e07964636ce'
Author = 'JamesBrundage'
CompanyName = 'Start-Automating'
Copyright = '(c) 2025 Start-Automating.'
Description = 'Get JSON Linked Data with PowerShell'
FunctionsToExport = 'Get-JsonLD'
AliasesToExport = 'jsonLD', 'json-ld'
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
Tags = @('json-ld','SEO','Web','PowerShellWeb')
# A URL to the license for this module.
ProjectURI = 'https://github.com/PowerShellWeb/JSON-LD'
LicenseURI = 'https://github.com/PowerShellWeb/JSON-LD/blob/main/LICENSE'
ReleaseNotes = @'

> Like It? [Star It](https://github.com/PowerShellWeb/JSON-LD)
> Love It? [Support It](https://github.com/sponsors/StartAutomating)

Get Linked Data from any page

## JSON-LD 0.0.1

* Initial Release of JSON-LD Module (#1)
* `Get-JsonLD` gets linked data (#2)
* `Get-JsonLD` is aliased to `jsonLD` and `json-ld`
'@
}
}

}

36 changes: 36 additions & 0 deletions JSON-LD.psm1
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
$commandsPath = Join-Path $PSScriptRoot Commands
:ToIncludeFiles foreach ($file in (Get-ChildItem -Path "$commandsPath" -Filter "*-*" -Recurse)) {
if ($file.Extension -ne '.ps1') { continue } # Skip if the extension is not .ps1
foreach ($exclusion in '\.[^\.]+\.ps1$') {
if (-not $exclusion) { continue }
if ($file.Name -match $exclusion) {
continue ToIncludeFiles # Skip excluded files
}
}
. $file.FullName
}

$myModule = $MyInvocation.MyCommand.ScriptBlock.Module
$ExecutionContext.SessionState.PSVariable.Set($myModule.Name, $myModule)
$myModule.pstypenames.insert(0, $myModule.Name)

New-PSDrive -Name $MyModule.Name -PSProvider FileSystem -Scope Global -Root $PSScriptRoot -ErrorAction Ignore

if ($home) {
$MyModuleProfileDirectory = Join-Path ([Environment]::GetFolderPath("LocalApplicationData")) $MyModule.Name
if (-not (Test-Path $MyModuleProfileDirectory)) {
$null = New-Item -ItemType Directory -Path $MyModuleProfileDirectory -Force
}
New-PSDrive -Name "My$($MyModule.Name)" -PSProvider FileSystem -Scope Global -Root $MyModuleProfileDirectory -ErrorAction Ignore
}

# Set a script variable of this, set to the module
# (so all scripts in this scope default to the correct `$this`)
$script:this = $myModule

#region Custom
#endregion Custom

Export-ModuleMember -Alias * -Function * -Variable $myModule.Name


15 changes: 15 additions & 0 deletions JSON-LD.tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
describe 'JSON-LD' {
context 'JSON-LD is a standard for embedding information in web pages' {
it 'can get information about a movie' {
$result = Get-JsonLD -Url 'https://www.imdb.com/title/tt0211915/'
$result.pstypenames | Should -Not -BeNullOrEmpty
$result.pstypenames | Should -Contain 'https://schema.org/Movie'

}
it 'can get information a schema' {
Get-JsonLD https://schema.org/Movie |
Select-Object -ExpandProperty pstypenames -Unique |
Should -Contain 'rdf:Property'
}
}
}
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,26 @@
# JSON-LD

Get JSON Linked Data with PowerShell

Gets information stored in a page's [json-ld](https://json-ld.org/) (json linked data)

Many pages expose this information for search engine optimization.

## JSON-LD in PowerShell

JSON-LD is one of a number of ways you can get more information about a page.

This information can be useful in any number of fun and useful PowerShell scenarios

For example, let's get information about a movie.

~~~PowerShell
Get-JsonLD https://www.imdb.com/title/tt0211915/
~~~

Let's take things a step further, and get the information we can know about any movie:

~~~PowerShell
JsonLD https://schema.org/Movie
~~~

Loading