Hi orgmode folks,

There is a special case that might need a clarification in the orgmode implementation and/or the org-syntax [0]

The affiliated keyword, when it's before a dynamic block [1] it does not work.

Example:

#+NAME: test
#+BEGIN: something-that-generates-a-table
| State | ID | Task    | RESPONSIBLE |
|-------+----+---------+-------------|
| TODO  | T1 | [[file:/tmp/affiliated-keyword-dynamic-block.org::*My task][My task]] | Laura       | | TODO  | T2 | [[file:/tmp/affiliated-keyword-dynamic-block.org::*Task2][Task2]] | Anna        |
#+END:

It must be

#+BEGIN: something-that-generates-a-table
#+NAME: test
| State | ID | Task    | RESPONSIBLE |
|-------+----+---------+-------------|
| TODO  | T1 | [[file:/tmp/affiliated-keyword-dynamic-block.org::*My task][My task]] | Laura       | | TODO  | T2 | [[file:/tmp/affiliated-keyword-dynamic-block.org::*Task2][Task2]] | Anna        |
#+END:

But right now, this is not available for org-ql, org-kanban, propview (the things I am using)

Tested with orgmode version 9.7.10, org-ql 20241107.345 and org-kanban cb96fa3ae5 source

So It needs to be after the dynamic block declaration; and that forces all dynamic block to handle that kind of construction.

I think it is reasonable to say that a NAME given before a BEGIN dynamic block element, applies to the thing that the dynamic block generates

The ability to clearly identify elements of exported html document is nice to improve the visibility of things, for example here I experienced how a table that represents a kanban might be better visualized using css and js [2]

Coming back to the org syntax, I suspect that the table rows are not an exception, #+NAME before table rows is specifically what I am using to identify the table, and what does not work when there is in the middle the dynamic block

#+begin_src diff
-With the exception of comments, clocks, headings, inlinetasks, items, node properties, planning, property drawers, sections, and table rows, every other element type can be assigned attributes. +With the exception of comments, clocks, headings, inlinetasks, items, node properties, planning, property drawers, and sections, every other element type can be assigned attributes.
#+end_src

Cheers,
pinmacs

[0] section 4.3.8.2 https://orgmode.org/worg/org-syntax.html#Keywords

[1] https://orgmode.org/manual/Dynamic-Blocks.html

[2] (see screenshot in part 3, source shared too) https://github.com/gizmomogwai/org-kanban/issues/50#issuecomment-2719546145
#+TODO: TODO DONE
#+COLUMNS: %TODO(State) %CUSTOM_ID(ID) %ITEM(Task) %RESPONSIBLE
# #+EXPORT_FILE_NAME: /tmp/org-kanban
#+TITLE: org-kanban html example
#+AUTHOR: Name

#+ATTR_HTML: :id abstract
#+begin_abstract
In this example I test different dynamic blocks and NAME keyword
#+end_abstract

#+OPTIONS: prop:t toc:nil tags:not-in-toc d:(not "BACKLINKS" not "TRACE")

#+LANGUAGE: en

#+TOC: headlines 3

run these exports to test:

#+name: sourceblock_created_2025-03-12_14-06-44
#+begin_src emacs-lisp
(org-dblock-update t)
(org-html-export-to-html)
(org-gfm-export-to-markdown)
#+end_src

* Panel

** columnview

columnview works fine for =NAME= and =CAPTION=

#+BEGIN: columnview :id global :match "TODO={.+}-TODO=\"QUIT\"-TODO=\"DONE\"" :link t
#+NAME: test
#+CAPTION: Table with columnview
| State | ID | Task    | RESPONSIBLE |
|-------+----+---------+-------------|
| TODO  | T1 | [[file:/tmp/affiliated-keyword-dynamic-block.org::*My task][My task]] | Laura       |
| TODO  | T2 | [[file:/tmp/affiliated-keyword-dynamic-block.org::*Task2][Task2]]   | Anna        |
#+END:

** org-ql

org-ql does not work with =NAME= and =CAPTION=

# TODO caption keyword not working neither after begin neither after end
#+CAPTION: Table with org-ql
#+BEGIN: org-ql :query "todo:" :columns ((todo "State") ((property "CUSTOM_ID") "ID") (heading "Task") ((property "RESPONSIBLE") "Responsible"))
| State | ID | Task    | Responsible |
|-------+----+---------+-------------|
| TODO  | T1 | [[My task][My task]] | Laura       |
| TODO  | T2 | [[Task2][Task2]]   | Anna        |
#+END

** propview

org-ql does not work with =NAME= and =CAPTION=

I use this custom function sometimes to evaluate a link using that feature from propview

#+name: sourceblock_created_2025-03-12_14-06-12
#+begin_src emacs-lisp
(defun __item-cid ()
  "link for propview when using CUSTOM_ID"
  (concat "[[#" CUSTOM_ID "][" ITEM "]]"))
#+end_src

#+RESULTS: sourceblock_created_2025-03-12_14-06-12

# propview allows CAPTION keyword if it is before end, but not after begin
#   anyway, the caption does not render fine
#+BEGIN: propview :scope ("./org-kanban.org") :match "TODO={.+}-TODO=\"QUIT\"-TODO=\"DONE\"" :noquote all :cols (TODO CUSTOM_ID (__item-cid) RESPONSIBLE)  :colnames ("State" "ID" "Task" "Responsible")
| State | ID | Task    | Responsible |
|-------+----+---------+-------------|
| TODO  | T1 | [[#T1][My task]] | Laura       |
| TODO  | T2 | [[#T2][Task2]]   | Anna        |
|-------+----+---------+-------------|
|       |    |         |             |
#+END:

** org-kanban

#+name: sourceblock_created_2025-03-12_14-15-42
#+begin_export html
<style>
/* 1) Reset all table borders and spacing */
#kanban-table,
#kanban-table tr,
#kanban-table th,
#kanban-table td {
  border: none !important;
  border-color: transparent !important;
  padding: 0;
  margin: 0;
  background: none;
  box-sizing: border-box;
}

/* 2) Use border-spacing to add gaps (like "cards") */
#kanban-table {
  border-collapse: separate !important; 
  /* Adjust spacing between cells (horizontal, vertical) */
  border-spacing: 1rem 0.5rem; 
  width: 100%;
  /* Light background for the overall board area */
  background-color: #f5f5f5;
  padding: 1rem;
  /* Optional: center the table on the page */
  margin: 1rem auto;
}

/* 3) Style the column headers (TH) */
#kanban-table th {
  background-color: #eaeaea;
  font-weight: bold;
  text-align: center;
  padding: 0.75rem 1rem;
  border-radius: 6px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

/* 4) Style each cell (TD) as a "card" */
#kanban-table td {
  background-color: #ffffff;
  padding: 0.75rem 1rem;
  border-radius: 6px;
  vertical-align: top;
  text-align: center;
  /* Subtle shadow to make it look like a card */
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

  </style>

<script>
// Function to clean and reorder the kanban table
function cleanAndReorderKanbanTable() {
  const table = document.getElementById("kanban-table");
  const tbody = table.querySelector("tbody");
  const rows = Array.from(tbody.querySelectorAll("tr"));

  // Get number of columns
  const columnCount = table.querySelectorAll("thead th").length;

  // Prepare arrays for columns content
  const columns = Array.from({ length: columnCount }, () => []);

  // Distribute cells into their respective column arrays if they contain links (content)
  rows.forEach((row) => {
    const cells = Array.from(row.children);
    cells.forEach((cell, idx) => {
      if (cell.querySelector("a")) {
        columns[idx].push(cell.innerHTML);
      }
    });
  });

  // Clear tbody content
  tbody.innerHTML = "";

  // Find max number of rows to create
  const maxRows = Math.max(...columns.map(col => col.length));

  // Rebuild tbody with content close to headers
  for (let i = 0; i < maxRows; i++) {
    const newRow = document.createElement("tr");
    let isRowEmpty = true;

    for (let j = 0; j < columnCount; j++) {
      const newCell = document.createElement("td");
      newCell.className = "org-left";

      if (columns[j][i]) {
        newCell.innerHTML = columns[j][i];
        isRowEmpty = false;
      } else {
        newCell.innerHTML = "&nbsp;";
        newCell.style.visibility = "hidden";
      }

      newRow.appendChild(newCell);
    }

    // Append only if row is not empty (all &nbsp;)
    if (!isRowEmpty) {
      tbody.appendChild(newRow);
    }
  }
}

// Run the function on page load or after DOM is ready
document.addEventListener("DOMContentLoaded", cleanAndReorderKanbanTable);
</script>
#+end_export

not working =#+NAME: kanban-table= introduced by hand

not working specific ID, useful to give kanban a styling, but that also might need (setq org-html-prefer-user-labels t)

# #+NAME: kanban-table
# #+BEGIN: kanban :layout (";" . 15)

# #+NAME: kanban-table

#+BEGIN: kanban :caption "my table" :name kanban-table
#+CAPTION: my table
#+NAME: kanban-table
| TODO    | DONE  |
|---------+-------|
| [[file:org-kanban.org::#T1][My task]] |       |
| [[file:org-kanban.org::#T2][Task2]]   |       |
|         | [[file:org-kanban.org::#T3][Task3]] |
#+END


* Active Tasks

** TODO My task
:PROPERTIES:
:RESPONSIBLE: Laura
:CUSTOM_ID: T1
:END:

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content


** TODO Task2
:PROPERTIES:
:RESPONSIBLE: Anna
:CUSTOM_ID: T2
:END:

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

** DONE Task3
CLOSED: [2025-03-12 Wed 13:17]
:PROPERTIES:
:CUSTOM_ID: T3
:END:

Content

Content

Content

Content

Content

Reply via email to