diff --git a/.github/workflows/check-branch.yml b/.github/workflows/check-branch.yml index 1e2d24a..e79864e 100644 --- a/.github/workflows/check-branch.yml +++ b/.github/workflows/check-branch.yml @@ -8,13 +8,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Comment PR - if: github.base_ref == 'master' && github.head_ref != 'next' + if: github.base_ref == 'master' && github.head_ref != 'staging' uses: thollander/actions-comment-pull-request@v2 with: message: | We regret to inform you that you are currently not able to merge your changes into the master branch due to restrictions applied by our SRE team. To proceed with merging your changes, we kindly request that you create a pull request from the next branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch. - name: Check branch - if: github.base_ref == 'master' && github.head_ref != 'next' + if: github.base_ref == 'master' && github.head_ref != 'staging' run: | echo "ERROR: We regret to inform you that you are currently not able to merge your changes into the master branch due to restrictions applied by our SRE team. To proceed with merging your changes, we kindly request that you create a pull request from the next branch. Our team will then review the changes and work with you to ensure a successful merge into the master branch." exit 1 \ No newline at end of file diff --git a/.github/workflows/issues-jira.yml b/.github/workflows/issues-jira.yml new file mode 100644 index 0000000..7bf0469 --- /dev/null +++ b/.github/workflows/issues-jira.yml @@ -0,0 +1,31 @@ +name: Create Jira Ticket for Github Issue + +on: + issues: + types: [opened] + +jobs: + issue-jira: + runs-on: ubuntu-latest + steps: + + - name: Login to Jira + uses: atlassian/gajira-login@master + env: + JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} + JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} + JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} + + - name: Create Jira Issue + id: create_jira + uses: atlassian/gajira-create@master + with: + project: ${{ secrets.JIRA_PROJECT }} + issuetype: ${{ secrets.JIRA_ISSUE_TYPE }} + summary: Github | Issue | ${{ github.event.repository.name }} | ${{ github.event.issue.title }} + description: | + *GitHub Issue:* ${{ github.event.issue.html_url }} + + *Description:* + ${{ github.event.issue.body }} + fields: "${{ secrets.ISSUES_JIRA_FIELDS }}" \ No newline at end of file diff --git a/.github/workflows/jira.yml b/.github/workflows/jira.yml deleted file mode 100644 index caa4bbd..0000000 --- a/.github/workflows/jira.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Create JIRA ISSUE -on: - pull_request: - types: [opened] -jobs: - security-jira: - if: ${{ github.actor == 'dependabot[bot]' || github.actor == 'snyk-bot' || contains(github.event.pull_request.head.ref, 'snyk-fix-') || contains(github.event.pull_request.head.ref, 'snyk-upgrade-')}} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Login into JIRA - uses: atlassian/gajira-login@master - env: - JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} - JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - - name: Create a JIRA Issue - id: create - uses: atlassian/gajira-create@master - with: - project: ${{ secrets.JIRA_PROJECT }} - issuetype: ${{ secrets.JIRA_ISSUE_TYPE }} - summary: | - ${{ github.event.pull_request.title }} - description: | - PR: ${{ github.event.pull_request.html_url }} - - fields: "${{ secrets.JIRA_FIELDS }}" - - name: Transition issue - uses: atlassian/gajira-transition@v3 - with: - issue: ${{ steps.create.outputs.issue }} - transition: ${{ secrets.JIRA_TRANSITION }} diff --git a/.github/workflows/policy-scan.yml b/.github/workflows/policy-scan.yml new file mode 100644 index 0000000..ff25923 --- /dev/null +++ b/.github/workflows/policy-scan.yml @@ -0,0 +1,46 @@ +name: Checks the security policy and configurations +on: + pull_request: + types: [opened, synchronize, reopened] +jobs: + security-policy: + if: github.event.repository.visibility == 'public' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@master + - name: Checks for SECURITY.md policy file + run: | + if ! [[ -f "SECURITY.md" || -f ".github/SECURITY.md" ]]; then exit 1; fi + security-license: + if: github.event.repository.visibility == 'public' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@master + - name: Checks for License file + run: | + expected_license_files=("LICENSE" "LICENSE.txt" "LICENSE.md" "License.txt") + license_file_found=false + current_year=$(date +"%Y") + + for license_file in "${expected_license_files[@]}"; do + if [ -f "$license_file" ]; then + license_file_found=true + # check the license file for the current year, if not exists, exit with error + if ! grep -q "$current_year" "$license_file"; then + echo "License file $license_file does not contain the current year." + exit 2 + fi + break + fi + done + + if [ "$license_file_found" = false ]; then + echo "No license file found. Please add a license file to the repository." + exit 1 + fi \ No newline at end of file diff --git a/.github/workflows/sast-scan.yml b/.github/workflows/sast-scan.yml deleted file mode 100644 index 3b9521a..0000000 --- a/.github/workflows/sast-scan.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: SAST Scan -on: - pull_request: - types: [opened, synchronize, reopened] -jobs: - security-sast: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Semgrep Scan - run: docker run -v /var/run/docker.sock:/var/run/docker.sock -v "${PWD}:/src" returntocorp/semgrep semgrep scan --config auto \ No newline at end of file diff --git a/.github/workflows/sca-scan.yml b/.github/workflows/sca-scan.yml index a642aef..485f1a5 100644 --- a/.github/workflows/sca-scan.yml +++ b/.github/workflows/sca-scan.yml @@ -3,7 +3,7 @@ on: pull_request: types: [opened, synchronize, reopened] jobs: - security-sca: + security: runs-on: ubuntu-latest steps: - name: Checkout repository @@ -16,4 +16,4 @@ jobs: - name: Run Snyk to check for vulnerabilities run: cd Contentstack.Utils && snyk test --fail-on=all env: - SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/secrets-scan.yml b/.github/workflows/secrets-scan.yml new file mode 100644 index 0000000..049c02f --- /dev/null +++ b/.github/workflows/secrets-scan.yml @@ -0,0 +1,29 @@ +name: Secrets Scan +on: + pull_request: + types: [opened, synchronize, reopened] +jobs: + security-secrets: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: '2' + ref: '${{ github.event.pull_request.head.ref }}' + - run: | + git reset --soft HEAD~1 + - name: Install Talisman + run: | + # Download Talisman + wget https://github.com/thoughtworks/talisman/releases/download/v1.37.0/talisman_linux_amd64 -O talisman + + # Checksum verification + checksum=$(sha256sum ./talisman | awk '{print $1}') + if [ "$checksum" != "8e0ae8bb7b160bf10c4fa1448beb04a32a35e63505b3dddff74a092bccaaa7e4" ]; then exit 1; fi + + # Make it executable + chmod +x talisman + - name: Run talisman + run: | + # Run Talisman with the pre-commit hook + ./talisman --githook pre-commit \ No newline at end of file diff --git a/.talismanrc b/.talismanrc index 4628b50..f94199e 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,4 +1,7 @@ fileignoreconfig: +- filename: .github/workflows/secrets-scan.yml + ignore_detectors: + - filecontent - filename: Contentstack.Utils/Models/Options.cs checksum: 3dc51f0de02429ef9a43b66e666ac4dbde41195e245f8ecc0094548ca8603245 - filename: Contentstack.Utils/Utils.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d6f68e..ac3b4b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +### Version: 1.0.6 +#### Date: June-09-2025 +- Used 'title' and 'target' in a tags + +### Version: 1.0.5 +#### Date: Oct-10-2024 +- Used Class Name and Id property in JsonToHTML converter ### Version: 1.0.4 #### Date: Aug-21-2024 diff --git a/CODEOWNERS b/CODEOWNERS index 0773923..1be7e0d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1 +1 @@ -* @contentstack/security-admin \ No newline at end of file +* @contentstack/security-admin diff --git a/Contentstack.Utils.Tests/Constants/JsonToHtmlConstants.cs b/Contentstack.Utils.Tests/Constants/JsonToHtmlConstants.cs index 061336e..2d6ecdb 100644 --- a/Contentstack.Utils.Tests/Constants/JsonToHtmlConstants.cs +++ b/Contentstack.Utils.Tests/Constants/JsonToHtmlConstants.cs @@ -16,10 +16,13 @@ public static class JsonToHtmlResultConstants public const string kTableHtml = "
Header 1 | Header 2 |
|---|---|
Body row 1 data 1 | Body row 1 data 2 |
Body row 2 data 1 | Body row 2 data 2 |
Praesent eu ex sed nibh venenatis pretium."; public const string kCodeHtml = "
Code template.";
- public const string kLinkInPHtml = "";
- public const string kLinkInPMailToHtml = "";
+ public const string kLinkInPHtml = "";
+ public const string kLinkInPMailToHtml = "";
public const string kLinkInPMailToTARGEtHtml = "";
public const string kEmbedHtml = "";
+ public const string stringClassIdResult = "This is a text to be ignored
"; + public const string kJSONRTEResult = "demoText is demoText
This is same
demoText2
demoText3demoText4
demoText3demoText2
"; + } public static class JsonToHtmlConstants @@ -47,15 +50,15 @@ public static class JsonToHtmlConstants public const string kEntryReferenceLinkJson = "{ \"uid\":\"06e34a7 5e4 e549d\", \"_version\":1, \"attrs\":{ }, \"children\":[{\"uid\":\"7626ea98e0e95d602210\",\"type\":\"reference\",\"attrs\":{\"target\":\"_self\",\"href\":\"/copy-of-entry-final-02\",\"display-type\":\"link\",\"entry-uid\":\"UID_08\",\"content-type-uid\":\"embeddedrte\",\"locale\":\"en-us\",\"type\":\"entry\",\"class-name\":\"embedded-entry\"},\"children\":[{\"text\":\"/copy-of-entry-final-02\"}]}],\"type\":\"doc\"}"; public const string kEntryReferenceInlineJson = "{ \"uid\":\"06e34a7 5e4 e549d\", \"_version\":1, \"attrs\":{ }, \"children\":[{\"uid\":\"506 4878f3f46 s21f0cbc aff\",\"type\":\"reference\",\"attrs\":{\"display-type\":\"inline\",\"entry-uid\":\"UID_09\",\"content-type-uid\":\"embeddedrte\",\"locale\":\"en-us\",\"type\":\"entry\",\"class-name\":\"embedded-entry\"},\"children\":[{\"text\":\"\"}]}],\"type\":\"doc\"}"; public const string kHRJson = "{ \"uid\":\"06e34a7 5e4 e549d\", \"_version\":1, \"attrs\":{ }, \"children\":[{\"uid\":\"f5a7b57 40a8a5c3 576828276b\",\"type\":\"hr\",\"children\":[{\"text\":\"\"}],\"attrs\":{ }}],\"type\":\"doc\"}"; - - + public const string classId = "{ \"uid\":\"06e34a7 5e4 e549d\", \"_version\":1, \"attrs\":{ }, \"children\":[{\"uid\":\"f5a7b57 40a8a5c3 576828276b\",\"type\":\"doc\",\"children\":[{\"text\":\"demoTextisdemoText\",\"classname\": \"c2\",\"id\": \"i2\"}],\"attrs\":{ }}],\"type\":\"text\"}"; + public const string stringClassId = "{ \"type\": \"doc\", \"attrs\": {}, \"uid\": \"8622288a91dc4c76985d776d2540b395\", \"children\": [ { \"type\": \"p\", \"uid\": \"396ee25abd0f4296a45eac63809450ef\", \"attrs\": {}, \"children\": [ { \"text\": \"This\", \"classname\": \"\", \"id\": \"i3\" }, { \"text\": \" is a \" }, { \"text\": \"text\", \"classname\": \"c1\", \"id\": \"i1\" }, { \"text\": \" to be \" }, { \"text\": \"ignored\", \"classname\": \"c2\", \"id\": \"\" } ] } ], \"_version\": 4 }"; public const string KAssetNode = "\"embedded_itemsConnection\": { \"edges\": [{ \"node\": { \"system\": { \"content_type_uid\": \"sys_assets\", \"uid\": \"UID_12\" }, \"created_at\": \"2020-08-19T09:13:32.785Z\", \"updated_at\": \"2020-08-19T09:13:32.785Z\", \"created_by\": \"Created_at\", \"updated_by\": \"Created_at\", \"content_type\": \"application/pdf\", \"file_size\": \"13264\", \"filename\": \"dummy.pdf\", \"url\":\"/v3/assetsUID_12/dummy.pdf\", \"_version\": 1, \"title\": \"dummy.pdf\" } } ]}"; public const string KEntryBlocNode = "\"embedded_itemsConnection\": { \"edges\": [{ \"node\": { \"title\": \"Update this title\", \"url\": \"\", \"locale\": \"en-us\", \"system\": { \"uid\": \"UID_07\", \"content_type_uid\": \"content_block\" }, \"_version\": 5, \"_in_progress\": false, \"multi_line\": \"\", \"rich_text_editor\": \"\" } } ]}"; public const string KEntryLinkNode = "\"embedded_itemsConnection\": { \"edges\": [{ \"node\": { \"title\": \"Entry with embedded entry\", \"rich_text_editor\": [ \"\" ], \"locale\": \"en-us\", \"system\": { \"uid\": \"UID_08\", \"content_type_uid\": \"embeddedrte\" }, \"_in_progress\": false } } ]}"; public const string KEntryInlineNode = "\"embedded_itemsConnection\": { \"edges\": [{ \"node\": { \"title\": \"updated title\", \"rich_text_editor\": [ \"\" ], \"locale\": \"en-us\", \"system\": { \"uid\": \"UID_09\", \"content_type_uid\": \"embeddedrte\", }, \"_in_progress\": false } } ]}"; public static string KGQLModel(string node, string embedConnection = null) { - return $"{{\"multiplerte\":{{\"json\":[{node}]{(embedConnection != null ? ","+embedConnection : "")} }}, \"singlerte\":{{\"json\":{node}{(embedConnection != null ? "," + embedConnection : "")}}} }}"; + return $"{{\"multiplerte\":{{\"json\":[{node}]{(embedConnection != null ? "," + embedConnection : "")} }}, \"singlerte\":{{\"json\":{node}{(embedConnection != null ? "," + embedConnection : "")}}} }}"; } public const string kAssetMeta = "{\"uid\":\"asset_uid\",\"created_by\":\"create_by\",\"updated_by\":\"update_by\",\"content_type\":\"image/jpeg\",\"file_size\":\"62181\",\"tags\":[],\"filename\":\"crop_area.jpeg\",\"url\":\"http://image.contenstack.com/crop_area.jpeg\",\"is_dir\":false,\"parent_uid\":null,\"path\":[],\"_version\":1,\"title\":\"crop_area.jpeg\",\"dimension\":{\"height\":712,\"width\":864},\"_metadata\":{\"extensions\":{\"extension_uid\":{\"local_metadata\":{\"local_data\":\"main\",\"presets\":[{\"uid\":\"preset_01\",\"name\":\"Local Preset\",\"options\":{\"transform\":{\"height\":500,\"width\":500,\"flip-mode\":\"horiz\",\"rotate\":40},\"focal-point\":{\"x\":-0.668935003427432,\"y\":-0.9220385351936531},\"quality\":\"100\",\"image-type\":\"jpeg\"}},{\"uid\":\"preset_02\",\"name\":\"WithCrop\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":\"569.6\",\"width\":\"569.6\",\"flip-mode\":\"both\"},\"image-type\":\"jpeg\",\"crop\":{\"height\":\"569.6\",\"width\":\"569.6\",\"x\":\"147.2\",\"y\":\"71.2\"}}},{\"uid\":\"preset_03\",\"name\":\"Filter\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":712,\"width\":864},\"image-type\":\"jpeg\",\"effects\":{\"brightness\":52,\"contrast\":15,\"saturate\":-30,\"blur\":16,\"sharpen\":{\"amount\":9,\"radius\":669,\"threshold\":207}}}}]},\"global_metadata\":{\"presets\":[{\"uid\":\"preset_04\",\"name\":\"Global Preset\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":\"712\",\"width\":\"864\",\"flip-mode\":\"verti\"},\"image-type\":\"jpeg\"}}]}}}}}"; @@ -64,6 +67,7 @@ public static string KGQLModel(string node, string embedConnection = null) public const string kAssetPresets = "{\"uid\":\"asset_uid\",\"created_by\":\"create_by\",\"updated_by\":\"update_by\",\"content_type\":\"image/jpeg\",\"file_size\":\"62181\",\"tags\":[],\"filename\":\"crop_area.jpeg\",\"url\":\"http://image.contenstack.com/crop_area.jpeg\",\"is_dir\":false,\"parent_uid\":null,\"path\":[],\"_version\":1,\"title\":\"crop_area.jpeg\",\"dimension\":{\"height\":712,\"width\":864},\"_metadata\":{\"extensions\":{\"extension_uid\":{\"local_metadata\":{\"local_data\":\"main\",\"presets\":[{\"uid\":\"preset_01\",\"name\":\"Local Preset\",\"options\":{}},{\"uid\":\"preset_02\",\"name\":\"WithCrop\",\"options\":{\"quality\":\"100\",\"transform\":{},\"image-type\":\"jpeg\",\"crop\":{}}},{\"uid\":\"preset_03\",\"name\":\"Filter\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":712,\"width\":864},\"image-type\":\"jpeg\",\"effects\":{}}}]},\"global_metadata\":{\"presets\":[{\"uid\":\"preset_04\",\"name\":\"Global Preset\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":\"712\",\"width\":\"864\",\"flip-mode\":\"verti\"},\"image-type\":\"jpeg\"}}]}}}}}"; public const string kAsset = "{\"uid\":\"asset_uid\",\"created_by\":\"create_by\",\"updated_by\":\"update_by\",\"content_type\":\"image/jpeg\",\"file_size\":\"62181\",\"tags\":[],\"filename\":\"crop_area.jpeg\",\"url\":\"http://image.contenstack.com/crop_area.jpeg\",\"is_dir\":false,\"parent_uid\":null,\"path\":[],\"_version\":1,\"title\":\"crop_area.jpeg\",\"dimension\":{\"height\":712,\"width\":864},\"_metadata\":{}}"; public const string kAssetMetaURLQuery = "{\"uid\":\"asset_uid\",\"created_by\":\"create_by\",\"updated_by\":\"update_by\",\"content_type\":\"image/jpeg\",\"file_size\":\"62181\",\"tags\":[],\"filename\":\"crop_area.jpeg\",\"url\":\"http://image.contenstack.com/crop_area.jpeg?render=full&noval\",\"is_dir\":false,\"parent_uid\":null,\"path\":[],\"_version\":1,\"title\":\"crop_area.jpeg\",\"dimension\":{\"height\":712,\"width\":864},\"_metadata\":{\"extensions\":{\"extension_uid\":{\"local_metadata\":{\"local_data\":\"main\",\"presets\":[{\"uid\":\"preset_01\",\"name\":\"Local Preset\",\"options\":{\"transform\":{\"height\":500,\"width\":500,\"flip-mode\":\"horiz\",\"rotate\":40},\"focal-point\":{\"x\":-0.668935003427432,\"y\":-0.9220385351936531},\"quality\":\"100\",\"image-type\":\"jpeg\"}},{\"uid\":\"preset_02\",\"name\":\"WithCrop\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":\"569.6\",\"width\":\"569.6\",\"flip-mode\":\"both\"},\"image-type\":\"jpeg\",\"crop\":{\"height\":\"569.6\",\"width\":\"569.6\",\"x\":\"147.2\",\"y\":\"71.2\"}}},{\"uid\":\"preset_03\",\"name\":\"Filter\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":712,\"width\":864},\"image-type\":\"jpeg\",\"effects\":{\"brightness\":52,\"contrast\":15,\"saturate\":-30,\"blur\":16,\"sharpen\":{\"amount\":9,\"radius\":669,\"threshold\":207}}}}]},\"global_metadata\":{\"presets\":[{\"uid\":\"preset_04\",\"name\":\"Global Preset\",\"options\":{\"quality\":\"100\",\"transform\":{\"height\":\"712\",\"width\":\"864\",\"flip-mode\":\"verti\"},\"image-type\":\"jpeg\"}}]}}}}}"; + public const string kJSONRTE = "{ \"uid\":\"uid\",\"_version\":1,\"locale\":\"en-us\",\"children\":[{\"type\":\"p\",\"children\":[{\"text\":\"demoText\",\"bold\":true},{\"text\":\" is\",\"underline\":true},{\"text\":\" demoText\",\"italic\":true}]},{\"type\":\"p\",\"children\":[{\"text\":\"This\",\"italic\":true,\"subscript\":true},{\"text\":\" \",\"italic\":true},{\"text\":\"is\",\"italic\":true,\"superscript\":true},{\"text\":\" \",\"italic\":true},{\"text\":\"same \",\"italic\":true,\"strikethrough\":true}]},{\"type\":\"p\",\"children\":[{\"text\":\"demoText2\",\"strikethrough\":true,\"inlineCode\":true}]},{\"type\":\"p\",\"children\":[{\"text\":\"demoText3\",\"strikethrough\":true,\"inlineCode\":true},{\"text\":\"demoText4\"}]},{\"type\":\"p\",\"children\":[{\"text\":\"demoText3\"},{\"type\":\"a\",\"attrs\":{\"url\":\"https://www.google.com/\",\"target\":\"_blank\",\"title\":\"demoText5\"},\"children\":[{\"text\":\"demoText2\"}]}]}],\"type\":\"doc\"}"; } } diff --git a/Contentstack.Utils.Tests/DefaultRenderTest.cs b/Contentstack.Utils.Tests/DefaultRenderTest.cs index 776f6c9..a13bd5b 100644 --- a/Contentstack.Utils.Tests/DefaultRenderTest.cs +++ b/Contentstack.Utils.Tests/DefaultRenderTest.cs @@ -1,4 +1,4 @@ -using Contentstack.Utils.Models; +using Contentstack.Utils.Models; using Xunit; using Contentstack.Utils.Tests.Mocks; using Contentstack.Utils.Enums; @@ -178,7 +178,7 @@ public void testLinkhDocument() string result = defaultRender.RenderNode("a", nodeLink, (nodes) => { return text; }); - Assert.Equal($"{text}", result); + Assert.Equal($"Text To set Link", result); } [Fact] diff --git a/Contentstack.Utils.Tests/JsonToHtmlTest.cs b/Contentstack.Utils.Tests/JsonToHtmlTest.cs index 62c06e9..e49da43 100644 --- a/Contentstack.Utils.Tests/JsonToHtmlTest.cs +++ b/Contentstack.Utils.Tests/JsonToHtmlTest.cs @@ -479,5 +479,23 @@ public void Should_Return_Result_For_Array_Hr_Document() Assert.Equal(new List" + embeddedObject.Uid + "
"; + string renderString = "" + embeddedObject.Uid + "
"; if (embeddedObject is IEmbeddedEntry) { - renderString += "Content type: " + ((IEmbeddedEntry)embeddedObject).Title + "
"; + renderString += "Content type: " + ((IEmbeddedEntry)embeddedObject).Title + "
"; } else { - renderString += "Content type: " + embeddedObject.ContentTypeUid + "
"; + renderString += "Content type: " + embeddedObject.ContentTypeUid + "
"; } renderString = renderString + "{callBack(node.children)}
"; case "a": - if (node.attrs.ContainsKey("url")) + if (node.attrs?.ContainsKey("url")==true) { href = (string)node.attrs["url"]; } - return $"{callBack(node.children)}"; + if (node.attrs?.ContainsKey("target") == true) + { + target = (string)node.attrs["target"]; + } + if (node.attrs?.ContainsKey("title") == true) + { + title = (string)node.attrs["title"]; + } + return $"{callBack(node.children)}"; + case "img": if (node.attrs.ContainsKey("url")) { diff --git a/Contentstack.Utils/Utils.cs b/Contentstack.Utils/Utils.cs index 34b6a96..81f4c00 100644 --- a/Contentstack.Utils/Utils.cs +++ b/Contentstack.Utils/Utils.cs @@ -159,6 +159,10 @@ private static string textToHtml(TextNode textNode, Options options) { text = options.RenderMark(MarkType.Bold, text: text); } + if (!string.IsNullOrEmpty(textNode.classname) || !string.IsNullOrEmpty(textNode.id)) + { + text = options.RenderMark(MarkType.Class, text: text, textNode.classname, textNode.id); + } return text; } diff --git a/Directory.Build.props b/Directory.Build.props index d5c9309..2a251d5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,5 @@