Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 5 additions & 14 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
Please:

* [Like](https://github.com/PoshWeb/OpenGraph)
* [Share](https://github.com/PoshWeb/OpenGraph)
* [Subscribe](https://github.com/PoshWeb/)
* [Support](https://github.com/sponsors/StartAutomating)

---

## OpenGraph 0.1.1

* Simplified Module Scaffolding (#14)
* Supporting open or closed tags (#15)
* `Get-OpenGraph -Html` supports direct content (#16)
* `Get-OpenGraph -Url` is now positional and pipeable (#17)
* Improving README (#18)
* `Get-OpenGraph` now supports unclosed `<meta>` tags (#23)
* `Test-OpenGraph` and `Test-OGP` are aliases of `Get-OpenGraph` (#22).
* Additionally, `Get-OpenGraph` now outputs `$false` when no OpenGraph tags are found.
* `Get-OpenGraph` now accepts any pipeline input and number of arguments (#21)
* `Get-OpenGraph` correctly outputs cached results (#20)

---

Expand Down
145 changes: 85 additions & 60 deletions Commands/Get-OpenGraph.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,22 @@ function Get-OpenGraph
'https://msnbc.com/',
'https://fox.com/' |
Get-OpenGraph
.LINK
https://ogp.me/
.EXAMPLE
OpenGraph https://posh.pckt.blog/static-sites-are-simple-6u51kgj
#>
[Alias('openGraph','ogp')]
[Alias('openGraph','ogp','Test-OpenGraph', 'Test-OGP')]
[CmdletBinding(PositionalBinding=$false)]
param(
param(
# A list of any arguments.
# This allows the command to take natural input.
[Parameter(ValueFromRemainingArguments)]
[Alias('Argument','Arguments','Args')]
[PSObject[]]
$ArgumentList,

# The URL that may contain Open Graph metadata
[Parameter(Position=0,ValueFromPipeline,ValueFromPipelineByPropertyName)]
[Uri]
[Parameter(ValueFromPipelineByPropertyName)]
[string]
$Url,

# Any HTML that may contain open graph metadata.
Expand All @@ -42,75 +49,93 @@ function Get-OpenGraph
# If set, forces the function to retrieve the Open Graph metadata even if it is already cached.
[Parameter(ValueFromPipelineByPropertyName)]
[switch]
$Force
$Force,

# Any number of input objects
[Parameter(ValueFromPipeline)]
[Alias('Input')]
[PSObject[]]
$InputObject
)

begin {
# Make a regex to match meta tags
# We will match both open and closed tags.
$metaRegex = [Regex]::new('<meta.+?/?>','IgnoreCase','00:00:00.1')
# If we do not have a cache
if (-not $script:Cache) {
# create one.
$script:Cache = [Ordered]@{}
}
if (-not $script:OpenGraphCache) {
$script:OpenGraphCache = [Ordered]@{}
}
}

process {
# Declare an empty object to hold the Open Graph metadata
$openGraphMetadata = [Ordered]@{PSTypeName='OpenGraph'}
if ($Url -and -not $PSBoundParameters['html']) {
# If the url is an absolute url with a scheme or http or https.
if ($url.Scheme -in 'http', 'https') {
# Get the url (if it is not cached).
if (-not $script:Cache[$url] -or $Force) {
$script:Cache[$url] =try {
Invoke-RestMethod -Uri $Url
} catch { $_ }
}
$html = $script:Cache[$url]
}
# Otherwise, see if the path exists
elseif (Test-Path $url)
{
# and get content from that path.
$html = Get-Content "$url" -Raw
}
# Turn any of our strongly bound parameters into arguments
if ($Url) {
$argumentList = @($argumentList) + $url
}

# If we had any html,
if ($html) {
# find all of the `<meta>` tags.
foreach ($match in $metaRegex.Matches($html)) {
# Try to make them XML
$matchXml = "$match" -as [xml]
# If that fails,
if (-not $matchXml) {
# try once more after explicitly closing the end tag.
$matchXml = $match -replace '>$', '/>' -as [xml]
# If any data was provided
if ($Data) {
$argumentList = @($argumentList) + $Data
}
if ($InputObject) {
$ArgumentList = @($ArgumentList) + $InputObject
}

:nextArgument foreach ($argument in $argumentList) {
# Declare an empty object to hold the Open Graph metadata
if (-not $argument) { continue }
$openGraphMetadata = [Ordered]@{PSTypeName='OpenGraph'}
$url, $data = $null, $null

if ($argument -as [uri]) {
$url = $argument -as [uri]
} elseif ($argument -is [Collections.IDictionary]) {
$data = $argument
} else {
Write-Warning "Only [uri] and [Collections.IDictionary] supported: $argument"
continue nextArgument
}

if ($Url) {
if ($script:OpenGraphCache[$url] -and -not $Force) {
foreach ($key in $script:OpenGraphCache[$url].Keys) {
$openGraphMetadata[$key] =
$script:OpenGraphCache[$url][$key]
}
([PSCustomObject]$script:OpenGraphCache[$url])
continue nextArgument
}
# If the meta tag contained a property and content,
if ($matchXml.meta.property -and $matchXml.meta.content) {
# we will add it to our openGraph metadata.
$openGraphMetadata[
$matchXml.meta.property
] = $matchXml.meta.content

$restResponse = Invoke-RestMethod -Uri $Url

foreach ($match in $metaRegex.Matches("$restResponse")) {
$matchXml = (
# close unclosed `<meta>` tags.
"$match" -replace '/?>$','/>'
) -as [xml]

if ($matchXml.meta.property -and $matchXml.meta.content) {
$openGraphMetadata[$matchXml.meta.property] = $matchXml.meta.content
}
}

$script:OpenGraphCache[$url] = $openGraphMetadata
}
}

# If any data was provided
if ($Data) {
# copy it into open graph metadata
foreach ($key in $Data.Keys) {
$openGraphMetadata[$key] = $Data[$key]
if ($Data) {
foreach ($key in $Data.Keys) {
$openGraphMetadata[$key] = $Data[$key]
}
}

# If there was no metadata
if (-not $openGraphMetadata.Count) {
# output false (so `Test-` verb scenarios are met)
$false
# and continue to the next argument.
continue nextArgument
}
}

# If there was no open graph metadata, return nothing.
if (-not $openGraphMetadata.Count) { return }

# Otherwise, return our OpenGraph metadata
[PSCustomObject]$openGraphMetadata
[PSCustomObject]$openGraphMetadata
}
}
}
16 changes: 8 additions & 8 deletions OpenGraph.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
RootModule = 'OpenGraph.psm1'
ModuleVersion = '0.1.1'
GUID = 'be4e4070-1ea6-4a2e-8b6a-c6b7755e5ace'
Author = 'JamesBrundage'
Author = 'James Brundage'
CompanyName = 'Start-Automating'
Copyright = '(c) 2025 Start-Automating'
Copyright = '(c) 2025-2026 Start-Automating'
Description = 'Get OpenGraph with PowerShell'
FunctionsToExport = 'Get-OpenGraph'
AliasesToExport = 'OpenGraph', 'ogp'
AliasesToExport = 'OpenGraph', 'ogp', 'Test-OpenGraph', 'Test-OGP'
TypesToProcess = 'OpenGraph.types.ps1xml'
PrivateData = @{
PSData = @{
Expand All @@ -17,11 +17,11 @@
ReleaseNotes = @'
## OpenGraph 0.1.1

* Simplified Module Scaffolding (#14)
* Supporting open or closed tags (#15)
* `Get-OpenGraph -Html` supports direct content (#16)
* `Get-OpenGraph -Url` is now positional and pipeable (#17)
* Improving README (#18)
* `Get-OpenGraph` now supports unclosed `<meta>` tags (#23)
* `Test-OpenGraph` and `Test-OGP` are aliases of `Get-OpenGraph` (#22).
* Additionally, `Get-OpenGraph` now outputs `$false` when no OpenGraph tags are found.
* `Get-OpenGraph` now accepts any pipeline input and number of arguments (#21)
* `Get-OpenGraph` correctly outputs cached results (#20)

---

Expand Down
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Import-Module OpenGraph -PassThru
You can also clone the repo and import the module locally:

~~~PowerShell
git clone https://github.com/PoshWeb/OpenGraph
git clone https://github.com/PowerShellWeb/OpenGraph
cd ./OpenGraph
Import-Module ./ -PassThru
~~~
Expand All @@ -40,10 +40,11 @@ This function retrieves the Open Graph metadata from a given URL and returns it

|Name|Type|Description|
|-|-|-|
|Url|Uri|The URL that may contain Open Graph metadata|
|Html|String|Any HTML that may contain open graph metadata.|
|ArgumentList|PSObject[]|A list of any arguments. <br/>This allows the command to take natural input.|
|Url|String|The URL that may contain Open Graph metadata|
|Data|IDictionary|A dictionary of additional Open Graph metadata to include in the result|
|Force|SwitchParameter|If set, forces the function to retrieve the Open Graph metadata even if it is already cached.|
|InputObject|PSObject[]|Any number of input objects|

##### Examples
###### Example 1
Expand All @@ -57,15 +58,17 @@ Get-OpenGraph -Url https://abc.com/
'https://fox.com/' |
Get-OpenGraph
~~~
#### Links
* [https://ogp.me/](https://ogp.me/)
###### Example 3
~~~PowerShell

~~~
## Types
### OpenGraph
#### Members
|Name|MemberType|
|-|-|
|[ToString](Types/OpenGraph/ToString.ps1)|ScriptMethod|
|[get_HTML](Types/OpenGraph/get_HTML.ps1)|ScriptProperty|
> (c) 2025 Start-Automating
> (c) 2025-2026 Start-Automating

> [LICENSE](https://github.com/PoshWeb/OpenGraph/blob/main/LICENSE)
> [LICENSE](https://github.com/PowerShellWeb/OpenGraph/blob/main/LICENSE)
Loading